From 7048d9f6981f6fe0a5c5d90518b7ec38c28fb5f6 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Wed, 4 Dec 2019 17:12:00 +0900 Subject: [PATCH 01/37] compile files --- .gitignore | 1 + Makefile | 4 ++-- input_win.c | 13 +++++++------ itoi/grpwk.c | 39 +++++++++++++++++++++++++++++++++++++++ itoi/grpwk.h | 5 +++++ 5 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 itoi/grpwk.c create mode 100644 itoi/grpwk.h diff --git a/.gitignore b/.gitignore index ae1a368..1c0012e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ result !analyze.py .*/ *.o +Makefile ahocorasick/ *.vscode diff --git a/Makefile b/Makefile index e228cc6..a342fad 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,6 @@ PROG = grpwk CC = gcc CFLAGS = -W -Wall -Wextra -Wconversion -Wshadow -FILES = $(shell gcc test_distance.c -o distance | find ./ \( -name "*.c" \) \( -not -name "*test*" \)) +FILES = $(shell gcc test_distance.c -o distance | find . \( -name "*.c" \) \( -not -name "*test*" \)) default: - $(CC) $(CFLAGS) -o $(PROG) $(FILES) \ No newline at end of file + $(CC) $(CFLAGS) -o $(PROG) $(FILES) diff --git a/input_win.c b/input_win.c index 96de7ad..1d4c35c 100644 --- a/input_win.c +++ b/input_win.c @@ -1,24 +1,25 @@ #include #include #include +#include #include #include "string_s.h" // change here to include your files!! -#include "example/grpwk.h" +#include "itoi/grpwk.h" int main_prg(int, char **); int main(int argc, char **argv) { - __clock_t c_start, c_end; + clock_t c_start, c_end; c_start = clock(); main_prg(argc, argv); c_end = clock(); printf("%f\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); - return (0); + return 0; } int main_prg(int argc, char **argv) @@ -36,10 +37,10 @@ int main_prg(int argc, char **argv) t.len = strlen(t.str); // input s[] - int i = 0; - while (~fscanf(fp_in, "%s", s[i].str)) s[i++].len = strlen(s[i].str); + int counter = 0; + for (; fscanf(fp_in, "%s", s[counter].str) != EOF; ++counter) s[counter].len = strlen(s[counter].str); - fprintf(fp_out, "%s\n", grpwk(t, s, i)); + fprintf(fp_out, "%s\n", grpwk(t, s, counter)); return 0; } diff --git a/itoi/grpwk.c b/itoi/grpwk.c new file mode 100644 index 0000000..c55b844 --- /dev/null +++ b/itoi/grpwk.c @@ -0,0 +1,39 @@ +#include +#include +#include + +#include "grpwk.h" +#include "../ahocorasick.h" + +// outcome functions for testing +void callback_match_pos(void *arg, aho_match_t *m) { + char *text = (char *)arg; + + printf("match text: "); + for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); + + printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); +} + +char *grpwk(const string_s t, const string_s s[], int len) { + char *ans = (char *)malloc(sizeof(char) * 100); + + ahocorasick aho; + aho_init(&aho); + + aho_add_match_text(&aho, "ab", strlen("ab")); + aho_add_match_text(&aho, "abc", strlen("abc")); + aho_add_match_text(&aho, "ca", strlen("ca")); + + char test[] = "abcabcabcab"; + aho_create_trie(&aho); + aho_register_match_callback(&aho, callback_match_pos, (void *)test); + + trie_print(&aho.trie); + + sprintf(ans, "total match: %d\n", aho_search(&aho, test, strlen(test))); + + aho_destroy(&aho); + + return ans; +} diff --git a/itoi/grpwk.h b/itoi/grpwk.h new file mode 100644 index 0000000..1775c70 --- /dev/null +++ b/itoi/grpwk.h @@ -0,0 +1,5 @@ +#pragma once + +#include "../string_s.h" + +char *grpwk(const string_s t, const string_s s[], int len); From 094baf6f28e62565b30cf0261f58edfb5c60e0be Mon Sep 17 00:00:00 2001 From: pysan3 Date: Wed, 4 Dec 2019 21:06:51 +0900 Subject: [PATCH 02/37] test env created --- ahocorasick.c | 5 +++-- ahotext.c | 4 ++-- ahotext.h | 2 +- input_win.c | 25 ++++++++++++++++++++----- itoi/grpwk.c | 34 +++++++++++++++++++++------------- itoi/grpwk.h | 2 +- queue.c | 4 ++-- queue.h | 2 +- queue_test.c | 4 ++-- string_s.h | 4 +++- 10 files changed, 56 insertions(+), 30 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 3745f92..4113867 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -17,7 +17,6 @@ void aho_destroy(ahocorasick * restrict aho) { int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len) { if (aho->text_id == INT_MAX) return -1; - // printf("%d ", len); aho_text *text = text_init(aho->text_id++, data, len); if (text == NULL || text->data == NULL) return -1; @@ -66,7 +65,9 @@ void aho_clear_match_text(ahocorasick * restrict aho) { void aho_create_trie(ahocorasick * restrict aho) { trie_init(&aho->trie); - for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) if (!trie_add(&aho->trie, iter)) printf("error (unexpected input [^a-d])\n"); + for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) + if (!trie_add(&aho->trie, iter)) + printf("error (%s, %d)\n", iter->data, iter->len); trie_connect(&aho->trie); } diff --git a/ahotext.c b/ahotext.c index d4ef323..8698109 100644 --- a/ahotext.c +++ b/ahotext.c @@ -3,10 +3,10 @@ #include "ahotext.h" -aho_text *text_init(int id, const char *data, int len) { +aho_text *text_init(const int id, const char *data, const int len) { aho_text *text = (aho_text *)malloc(sizeof(aho_text)); text->id = id; - text->data = (char *)malloc(sizeof(char) * len); + text->data = (char *)malloc(sizeof(char) * (len + 1)); strcpy(text->data, data); text->len = len; text->prev = NULL; diff --git a/ahotext.h b/ahotext.h index 9ad90ab..9ee4e52 100644 --- a/ahotext.h +++ b/ahotext.h @@ -7,4 +7,4 @@ typedef struct _text { struct _text *prev, *next; } aho_text; -aho_text *text_init(int id, const char *data, int len); +aho_text *text_init(const int id, const char *data, const int len); diff --git a/input_win.c b/input_win.c index 1d4c35c..655c63b 100644 --- a/input_win.c +++ b/input_win.c @@ -2,6 +2,8 @@ #include #include #include +// #include +// #include #include #include "string_s.h" @@ -12,16 +14,26 @@ int main_prg(int, char **); int main(int argc, char **argv) { - clock_t c_start, c_end; + // struct rusage u; + // getrusage(RUSAGE_SELF, &u); + // struct timeval start = u.ru_utime; - c_start = clock(); + clock_t c_start = clock(), c_end; main_prg(argc, argv); + + // struct timeval end = u.ru_utime; c_end = clock(); printf("%f\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); + // fprintf(stderr, "%lf\n", (double)(end.tv_sec - start.tv_sec) + (double)(end.tv_usec - start.tv_usec) * 1e-6); return 0; } + +int sort_f(const void *a, const void *b) { + return ((string_s *)b)->len - ((string_s *)a)->len; +} + int main_prg(int argc, char **argv) { assert(argc == 3); @@ -30,16 +42,19 @@ int main_prg(int argc, char **argv) FILE *fp_out = fopen(argv[2], "w"); assert(fp_out != NULL); - string_s t, s[50000]; + char t[T_LENGTH]; + string_s s[50000]; // input t - fscanf(fp_in, "%s", t.str); - t.len = strlen(t.str); + fscanf(fp_in, "%s", t); // input s[] int counter = 0; for (; fscanf(fp_in, "%s", s[counter].str) != EOF; ++counter) s[counter].len = strlen(s[counter].str); + qsort(s, counter, sizeof(string_s), sort_f); + fp_in = fopen("data/dat0_ref", "r"); + fscanf(fp_in, "%s", t); fprintf(fp_out, "%s\n", grpwk(t, s, counter)); return 0; diff --git a/itoi/grpwk.c b/itoi/grpwk.c index c55b844..3296388 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -9,31 +9,39 @@ void callback_match_pos(void *arg, aho_match_t *m) { char *text = (char *)arg; - printf("match text: "); - for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); + // printf("match text: "); + // for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); - printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); + // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); } -char *grpwk(const string_s t, const string_s s[], int len) { - char *ans = (char *)malloc(sizeof(char) * 100); - +char *ahocoralike(const char *t, const string_s s[], int len) { ahocorasick aho; aho_init(&aho); - aho_add_match_text(&aho, "ab", strlen("ab")); - aho_add_match_text(&aho, "abc", strlen("abc")); - aho_add_match_text(&aho, "ca", strlen("ca")); + for (int i=0; i= 10; ++i) { + aho_add_match_text(&aho, s[i].str, s[i].len); + } - char test[] = "abcabcabcab"; aho_create_trie(&aho); - aho_register_match_callback(&aho, callback_match_pos, (void *)test); + // trie_print(&aho.trie); - trie_print(&aho.trie); + char *ans = (char *)malloc(sizeof(char) * (T_LENGTH + 1)); + // printf("test case: %s\n", t); - sprintf(ans, "total match: %d\n", aho_search(&aho, test, strlen(test))); + aho_register_match_callback(&aho, callback_match_pos, (void *)t); + sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); aho_destroy(&aho); return ans; } + +char *grpwk(const char *t, const string_s s[], int len) { + int i = 0; + // for (; isize >= MAX_SIZE) { - printf("キューの容量がいっぱいです\n"); + // printf("キューの容量がいっぱいです\n"); return; } que->data[que->back] = value; @@ -27,7 +27,7 @@ QUE_TYPE que_pop(queue *que) { if (que->size == 0) { - printf("キューの中身は空です\n"); + // printf("キューの中身は空です\n"); return NULL; } QUE_TYPE top = que->data[que->front]; diff --git a/queue.h b/queue.h index a80d3fe..494b775 100644 --- a/queue.h +++ b/queue.h @@ -6,7 +6,7 @@ #define QUEUE_H #define QUE_TYPE aho_node* -#define MAX_SIZE 50000 +#define MAX_SIZE 500000 typedef struct { diff --git a/queue_test.c b/queue_test.c index 85dd17f..f4caf4e 100644 --- a/queue_test.c +++ b/queue_test.c @@ -15,14 +15,14 @@ int main() for (i = 0; i < 5; i++) { que_push(&q, i + 1); - printQue(&q); + // printQue(&q); } for (i = 0; i < 3; i++) { a = que_pop(&q); printf("%d\n", a); } - printQue(&q); + // printQue(&q); printf("%d\n", q.size); return 0; } \ No newline at end of file diff --git a/string_s.h b/string_s.h index a1d9784..21b720b 100644 --- a/string_s.h +++ b/string_s.h @@ -3,4 +3,6 @@ typedef struct { char str[120]; int len; -} string_s; \ No newline at end of file +} string_s; + +#define T_LENGTH 400001 \ No newline at end of file From 69a8f5db02f92078f3629f840e24cb59eafa34d8 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Wed, 4 Dec 2019 21:28:21 +0900 Subject: [PATCH 03/37] file name changed: string_s.h -> string_info.h --- .gitignore | 1 + ahocorasick.c | 2 +- ahotrie.c | 2 +- compile.sh | 18 ++++++++++++++++++ example/grpwk.h | 4 ++-- input_win.c | 4 ++-- itoi/grpwk.c | 2 +- itoi/grpwk.h | 2 +- string_s.h => string_info.h | 0 9 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 compile.sh rename string_s.h => string_info.h (100%) diff --git a/.gitignore b/.gitignore index 1c0012e..1c1a0ce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ grpwk distance result *.sh +!compile.sh *.py !analyze.py .*/ diff --git a/ahocorasick.c b/ahocorasick.c index 4113867..81e2f64 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -104,4 +104,4 @@ void aho_print_match_text(ahocorasick * restrict aho) { for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) { printf("id: %d, text:%s, len:%d\n", iter->id, iter->data, iter->len); } -} \ No newline at end of file +} diff --git a/ahotrie.c b/ahotrie.c index dd284b2..5b72173 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -108,7 +108,7 @@ void trie_delete(aho_trie * restrict t) { int find_node(aho_node ** restrict node, const char text) { if (*node == NULL) return FALSE; - if (text - 'a' <= 3 && text - 'a' >= 0 && (*node)->child[text - 'a'] != NULL) { + if ((*node)->child[text - 'a'] != NULL && text - 'a' <= 3 && text - 'a' >= 0) { *node = (*node)->child[text - 'a']; return TRUE; } diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..8b814cb --- /dev/null +++ b/compile.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +PROG=grpwk +CC=gcc +CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" + +FILES=$(find -maxdepth 1 \( -name "*.c" \) \( -not -name "*test*" \)) +TEST=$(find $1 \( -name "*.c" \) \( -not -name "*test*" \)) +$CC $CFLAGS -o grpwk $FILES $TEST +$CC -o distance test_distance.c + +echo -------------result +echo -n "time : " +./grpwk data/dat$2_in result +./distance result data/dat$2_ref + +echo -------------output +cat result diff --git a/example/grpwk.h b/example/grpwk.h index 4a430d7..9308d4f 100644 --- a/example/grpwk.h +++ b/example/grpwk.h @@ -1,5 +1,5 @@ #pragma once -#include "../string_s.h" +#include "../string_info.h" -char *grpwk(const string_s t, const string_s s[], int len); \ No newline at end of file +char *grpwk(const char *t, const string_s s[], int len); \ No newline at end of file diff --git a/input_win.c b/input_win.c index 655c63b..9af2b5e 100644 --- a/input_win.c +++ b/input_win.c @@ -5,9 +5,9 @@ // #include // #include #include -#include "string_s.h" +#include "string_info.h" -// change here to include your files!! +// TODO: change here to include your files!! #include "itoi/grpwk.h" int main_prg(int, char **); diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 3296388..4ced41f 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -39,7 +39,7 @@ char *ahocoralike(const char *t, const string_s s[], int len) { char *grpwk(const char *t, const string_s s[], int len) { int i = 0; - // for (; i Date: Wed, 4 Dec 2019 23:47:20 +0900 Subject: [PATCH 04/37] test --- ahotext.c | 5 ++-- ahotext.h | 2 +- compile.sh | 28 ++++++++++++++++++--- example/grpwk.c | 2 +- input_win.c | 3 +-- itoi/ahocora.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ itoi/ahocora.h | 5 ++++ itoi/grpwk.c | 38 +++------------------------- test_ahocorasick.c | 2 +- 9 files changed, 102 insertions(+), 46 deletions(-) create mode 100644 itoi/ahocora.c create mode 100644 itoi/ahocora.h diff --git a/ahotext.c b/ahotext.c index 8698109..fe5da03 100644 --- a/ahotext.c +++ b/ahotext.c @@ -3,11 +3,10 @@ #include "ahotext.h" -aho_text *text_init(const int id, const char *data, const int len) { +aho_text *text_init(const int id, char *data, const int len) { aho_text *text = (aho_text *)malloc(sizeof(aho_text)); text->id = id; - text->data = (char *)malloc(sizeof(char) * (len + 1)); - strcpy(text->data, data); + text->data = data; text->len = len; text->prev = NULL; text->next = NULL; diff --git a/ahotext.h b/ahotext.h index 9ee4e52..604686a 100644 --- a/ahotext.h +++ b/ahotext.h @@ -7,4 +7,4 @@ typedef struct _text { struct _text *prev, *next; } aho_text; -aho_text *text_init(const int id, const char *data, const int len); +aho_text *text_init(const int id, char *data, const int len); diff --git a/compile.sh b/compile.sh index 8b814cb..b42c8fc 100644 --- a/compile.sh +++ b/compile.sh @@ -3,16 +3,38 @@ PROG=grpwk CC=gcc CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" +DIR="." +ID=0 + +usage_exit() { + echo "Usage: $0 [-n (no warning)] [-d ] [-t ]" +} + +while getopts :hnd:t: OPT +do + case $OPT in + n) CFLAGS="";; + d) DIR=$OPTARG;; + t) ID=$OPTARG;; + h) usage_exit;; + \?) usage_exit;; + esac +done +shift $(($OPTIND - 1)) FILES=$(find -maxdepth 1 \( -name "*.c" \) \( -not -name "*test*" \)) -TEST=$(find $1 \( -name "*.c" \) \( -not -name "*test*" \)) +TEST=$(find $DIR \( -name "*.c" \) \( -not -name "*test*" \)) + $CC $CFLAGS -o grpwk $FILES $TEST $CC -o distance test_distance.c echo -------------result echo -n "time : " -./grpwk data/dat$2_in result -./distance result data/dat$2_ref +./grpwk data/dat${ID}_in result +./distance result data/dat${ID}_ref + +rm distance +rm grpwk echo -------------output cat result diff --git a/example/grpwk.c b/example/grpwk.c index e4335ae..d22c750 100644 --- a/example/grpwk.c +++ b/example/grpwk.c @@ -3,7 +3,7 @@ #include "grpwk.h" -char *grpwk(const string_s t, const string_s s[], int len) { +char *grpwk(const char *t, const string_s s[], int len) { char *str = (char *)malloc(sizeof(char) * 100); sprintf(str, "I got %d data!", len); diff --git a/input_win.c b/input_win.c index 9af2b5e..dd2d8b0 100644 --- a/input_win.c +++ b/input_win.c @@ -47,14 +47,13 @@ int main_prg(int argc, char **argv) // input t fscanf(fp_in, "%s", t); + for (int i=0; i +#include +#include + +#include "../ahocorasick.h" +#include "ahocora.h" + +// outcome functions for testing +void callback_match_pos(void *arg, aho_match_t *m) { + char *text = (char *)arg; + + if (m->len > 20) { + printf("match text: "); + for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); + printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); + } +} + +int bitcount(unsigned long long bits) { + bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); + bits = (bits & 0x3333333333333333) + (bits >> 2 & 0x3333333333333333); + bits = (bits & 0x0f0f0f0f0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f0f0f0f0f); + bits = (bits & 0x00ff00ff00ff00ff) + (bits >> 8 & 0x00ff00ff00ff00ff); + bits = (bits & 0x0000ffff0000ffff) + (bits >> 16 & 0x0000ffff0000ffff); + bits = (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); + return bits; +} + +const char *convert(const char *s, const int len, const unsigned long long bitcheck) { + char *tmp = (char *)malloc(sizeof(char) * (len + 1)); + for (int i=0; i #include "grpwk.h" -#include "../ahocorasick.h" - -// outcome functions for testing -void callback_match_pos(void *arg, aho_match_t *m) { - char *text = (char *)arg; - - // printf("match text: "); - // for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); - - // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); -} - -char *ahocoralike(const char *t, const string_s s[], int len) { - ahocorasick aho; - aho_init(&aho); - - for (int i=0; i= 10; ++i) { - aho_add_match_text(&aho, s[i].str, s[i].len); - } - - aho_create_trie(&aho); - // trie_print(&aho.trie); - - char *ans = (char *)malloc(sizeof(char) * (T_LENGTH + 1)); - // printf("test case: %s\n", t); - - aho_register_match_callback(&aho, callback_match_pos, (void *)t); - sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); - - aho_destroy(&aho); - - return ans; -} +#include "ahocora.h" char *grpwk(const char *t, const string_s s[], int len) { int i = 0; - for (; i 40; ++i); + const string_s *a = &s[i]; - string_s *a = &s[i]; char *ans = ahocoralike(t, a, len - i); return ans; } diff --git a/test_ahocorasick.c b/test_ahocorasick.c index c2da942..518cc0a 100644 --- a/test_ahocorasick.c +++ b/test_ahocorasick.c @@ -77,7 +77,7 @@ int test_input(void) { FILE *fp = fopen("data/dat0_in", "r"); fscanf(fp, "%s", s); while (~fscanf(fp, "%s", s)) - if (strlen(s) >= 60) + if (strlen(s) >= 50) aho_add_match_text(&aho, s, strlen(s)); fp = fopen("data/dat0_ref", "r"); From 1259ed30554dbf78689f82dd384bb88010c57374 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Thu, 5 Dec 2019 00:16:52 +0900 Subject: [PATCH 05/37] revert Makefile --- Makefile | 13 ++++++++++--- distance | Bin 8600 -> 0 bytes itoi/grpwk.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) delete mode 100644 distance diff --git a/Makefile b/Makefile index a342fad..f3bad14 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,14 @@ PROG = grpwk +OBJS = input.o CC = gcc CFLAGS = -W -Wall -Wextra -Wconversion -Wshadow +LDFLAGS = -FILES = $(shell gcc test_distance.c -o distance | find . \( -name "*.c" \) \( -not -name "*test*" \)) -default: - $(CC) $(CFLAGS) -o $(PROG) $(FILES) +.SUFFIXES: .c + +$(PROG): $(OBJS) + $(CC) $(LDFLAGS) -o $(PROG) $^ +.c.o: + $(CC) $(CFLAGS) -c $< +clean: + rm $(OBJS) $(PROG) \ No newline at end of file diff --git a/distance b/distance deleted file mode 100644 index 6f8085529e46a439b6300c718f2bcf6c4102b156..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8600 zcmeHMeQZ_*S$p5OhQ^X~UM_vS0@T^%J3hv4KC4+_%emY7JhDmb)WWgwbGqgaOD zPl8cR&TF7Hu1mRv)UWvZ;8s8A?N;gtZ{QC%l0 zr3&el8I~tiJhD!%D3)RG;@$_)baO1X` zZS}rX!naknoBR`ZcXzLR6OA`_E!BB79>S=6$J~X~t;YE5u9g0g*X!Lk4z~Zflx+Dy z_TNrVgXt~6eh}EI0{HeK_{t)9Z4rE95xlPm{ypGcJodB#K%siR2;6HYL+{2z?_QKJ zK0z9eZ6cBw3de=6r;I@GaXmQjxE={aV*moFR5)pv+E6kYHzFcsBx8~sO(lX&O?o61 z48$Yg28RQBBpMIIq9?*o$vZiO`CuR#7rVPUTUzz4zWQu#tFIxO-!Amdp1pb~oD3g} zri^g1XK!mP5fAqS`eWqn*kB^Ayy+&jAd%Wwf>~3FhyKhNM3Ux;6ORx)uUAK-Sh1xd zp|JG&=rZCTSNd96ULr=JQ{sJq*YDg?6F;lgJL4A=UheTq0^_XTaGN--MXC>{X$!7g z$f6kw&c3K%&VsA0K=N-{aGEQeUQjss=5Miw3(k88l}uW2>ppwUf?M~Q z>lPdxoK4!uJLTF~+2}H_&_*YXl7;Kq$SdVjVxeIppoOYU_;qh+Mvn9WvYVY=K&o0# zI(6Obb*Zl+otiW|DfQ)~Q&VOyNWFw~YQpR}see=sovJ=Nk+qLZK$ofR-OkKwN3_iE zwUIx}?eFOtFWUoO+IZzJ@d|Bx=O4jZSaStF{_5V)CZSm4D zCaGvzW#7Vd#OK~{O8W1cqE_W}xI9n9@rLK5o9cPkYnSJpT4qkWJhMx4T+v>eH`c*n zKsl@+hsFGz+<6!@k=~+>?A%VdUaC)pHn#JAXfu^)@{ER`D`j=i9aNo@RI&G`;1ca2 zdf#jW49XqUo_Oa>i(6z~`qE2t3tHw!Ll7Ztth8z~Y_v@KOx>h5HcF^AGKm4DhSX3` zWv=ahO=G0VS)1wXtm%w| z>8y;L(E@<8i^Lt@`7?-_QsR$4dye>HW*x>GUN)Uw0$t2J_laao9=Syf>3F>1oRx7B zjH{z(=v_!xN1s%=KQ)ZWymr=o@tHDuMNU6eMh+Wac0W7mzBuWS)+3VbP^91uZG2SL z3(cybN;FL+e_+Ax0+yKqAgcyaIe_Y^%#ClQ;kpNHTw6VQ2 zA?>~jIZ8&^%o`u$El<2cBl&3GRBrOQHwgbD{)am=Z}@xtnCn&FcFL(-L-L?M^GRps z!>;O^a;;we#5uE@{EWV9c#WDMJro>kq_(VP8;0hV*FMd+$zfcW+l0X^FIv zRjX1W9EuuV=HKtF3N07%GXsBjJ9kj*LwnHVKNc3wK-Qw#7a*G<4?*rhKV2gnvz&U5 z_Ju|aJSB=dC^=3X5RPGwOWsoQBWO5kaNGd?7ZWocOii4-wbp>2R&v z<6iN_@{?lM`W>IWZ_`GC$sWs241-5&f)m+4hUWz8{2Qv9-{m=7(ptGh8*w^cb)Z%z zlWb4nX~cXF6V&4JJYCY_TKAN*-Q^uGZEl%Hv^}f1l6Th8Dinblu^Szbr#5aM@!}+*V7(5{?1r+h~e6+yu zUnY1S=Hp8Q&)0l>so-(U$IAtee?GoU@I1@MmkXYc`S=RK>oOm&5JLsV#VIPqbV1ye zy?@E~=AGis z?E1DAIt5mx8Eu&bwKTP5WV~cuz)bIaCPR7fXaoczJ_Rg)W63wc+Meyf~;6E;c|Dp)~9&oCseg4k_ z_bzUhs6PWAz(`rG|PfqQebY;FYj#;lgh+y{IWqKZZPYA|V} zjC3S|(?srGNjC=dAl)pbaH|wb=*MD-{y{52S}hFflk33mf5(Z~L|;TuT)q z(LGmG4-`CM`u)Rm`@warflUI397fhvPn{IOpmv`mY+{{;c=%sKdU>YEa&Ud&0X4A)LU6*GX==`J(}MGOLtro(M4f1E z_|U1sht)NR6_Z=N|9OtiE!d*)O*d1c%CO{fiz=2}&XfEM9@?tdp5slHUX)oA@1u;> zA!D`YxRm84CMs#SZv*}z&Il|ORY*ufw*I&Wn z1Txg8Y|n8x%SlD#_uJclO4+w49>?n}`MgQ?cjB?zKLw2Xgu`?G{;FZ+AmX3zHvEcu+xe0%%P zD|;S4j#pUH{I({${SQ${{m1t9|A#(cHAdcU{}Y=%pLbY#Y!jaQjotnf89F;~H*p-y z|0lKcS!ekx*t#wDe11BsE^L?wicGAtdGKBH_IS%wFLp$F#9O47m5>|`Hn%JJ> zRW4(DtK_-E9FooI{llu`=sWXyJX{~%*Jyro-I2|vOSD-aeaGgU-)ojqj9%FO5p|@U KXQGmJ`+ov>>WyUp diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 2e07383..f370345 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -7,7 +7,7 @@ char *grpwk(const char *t, const string_s s[], int len) { int i = 0; - for (; i 40; ++i); + for (; i 16; ++i); const string_s *a = &s[i]; char *ans = ahocoralike(t, a, len - i); From c090a018f18a21e7907601d35451a00214586b37 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 6 Dec 2019 01:34:30 +0900 Subject: [PATCH 06/37] test --- ahocorasick.c | 2 +- itoi/ahocora.c | 9 ++++----- itoi/grpwk.c | 2 +- queue.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 81e2f64..a5cc57b 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -88,7 +88,7 @@ int aho_search(ahocorasick * restrict aho, const char *data, int len) { match.len = result->len; match.pos = i - result->len + 1; - counter++; + if (match.len == 16) counter++; if (aho->callback_match) aho->callback_match(aho->callback_arg, &match); } diff --git a/itoi/ahocora.c b/itoi/ahocora.c index 9b7cae0..d6a95fa 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -9,7 +9,7 @@ void callback_match_pos(void *arg, aho_match_t *m) { char *text = (char *)arg; - if (m->len > 20) { + if (m->len >= 17) { printf("match text: "); for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); @@ -22,8 +22,7 @@ int bitcount(unsigned long long bits) { bits = (bits & 0x0f0f0f0f0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f0f0f0f0f); bits = (bits & 0x00ff00ff00ff00ff) + (bits >> 8 & 0x00ff00ff00ff00ff); bits = (bits & 0x0000ffff0000ffff) + (bits >> 16 & 0x0000ffff0000ffff); - bits = (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); - return bits; + return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); } const char *convert(const char *s, const int len, const unsigned long long bitcheck) { @@ -41,8 +40,8 @@ char *ahocoralike(const char *t, const string_s s[], const int len) { aho_init(&aho); for (int i=0; i 16; ++i); + for (; i 17; ++i); const string_s *a = &s[i]; char *ans = ahocoralike(t, a, len - i); diff --git a/queue.h b/queue.h index 494b775..f1001ec 100644 --- a/queue.h +++ b/queue.h @@ -6,7 +6,7 @@ #define QUEUE_H #define QUE_TYPE aho_node* -#define MAX_SIZE 500000 +#define MAX_SIZE 5000000 typedef struct { From 08b61b177f0bc8f87fed9dfd0bca05614ef2fcdc Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 6 Dec 2019 03:15:36 +0900 Subject: [PATCH 07/37] analyze --- analyze.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/analyze.py b/analyze.py index b130167..ab13d32 100644 --- a/analyze.py +++ b/analyze.py @@ -37,6 +37,19 @@ def sep_len(): # sep_len() +def mat(): + import matplotlib.pyplot as plt + import numpy as np + print('matplotlib') + x = [i+1 for i in range(85)] + y = [3902, 3686, 3282, 2947, 2767, 2380, 2173, 1896, 1715, 1571, 1382, 1288, 1104, 1044, 922, 821, 716, 699, 547, 520, 492, 463, 389, 360, 332, 287, 270, 220, 193, 184, 168, 146, 140, 107, 109, 91, 84, 85, 66, 66, 57, 58, 46, 52, 37, 33, 25, 19, 22, 24, 25, 23, 13, 21, 15, 10, 6, 7, 10, 11, 8, 4, 5, 7, 1, 7, 4, 3, 3, 9, 1, 3, 1, 1, 3, 2, 2, 3, 1, 1, 3, 1, 2, 1, 3] + print(len(y)) + plt.plot(np.array(x), np.array(y), label='sep_len') + plt.legend() + plt.show() + +# mat() + def x_len(): print('x_len') counter = [{} for i in range(5)] @@ -101,4 +114,4 @@ def duplication(): if t_count[k] != s_count[k]: print(k) -duplication() +# duplication() From ac88b3df240f02f03a3faca2c5a9df6c9e6469dc Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 6 Dec 2019 16:01:41 +0900 Subject: [PATCH 08/37] algo ver1 O(2^n) --- ahocorasick.c | 32 +++++++++++++++----------------- ahocorasick.h | 3 ++- ahotrie.c | 4 ++-- ahotrie.h | 2 +- itoi/ahocora.c | 25 +++++++++++++++---------- itoi/grpwk.c | 8 ++++---- itoi/grpwk.h | 3 +++ 7 files changed, 42 insertions(+), 35 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index a5cc57b..bfa4032 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -14,24 +14,17 @@ void aho_destroy(ahocorasick * restrict aho) { aho_clear_trie(aho); } -int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len) { +int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len, aho_text * restrict parent) { if (aho->text_id == INT_MAX) return -1; - aho_text *text = text_init(aho->text_id++, data, len); + aho_text *text = text_init(parent->id, data, len); if (text == NULL || text->data == NULL) return -1; - if (aho->head == NULL) { - aho->head = text; - aho->tail = text; - aho->text_count++; - return text->id; - } + trie_add(&aho->trie, text, parent); + free(text->data); + free(text); - aho->tail->next = text; - text->prev = aho->tail; - aho->tail = text; - aho->text_count++; - return text->id; + return parent->id; } int aho_del_match_text(ahocorasick * restrict aho, const int id) { @@ -65,9 +58,13 @@ void aho_clear_match_text(ahocorasick * restrict aho) { void aho_create_trie(ahocorasick * restrict aho) { trie_init(&aho->trie); - for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) - if (!trie_add(&aho->trie, iter)) - printf("error (%s, %d)\n", iter->data, iter->len); + // for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) + // if (!trie_add(&aho->trie, iter)) + // printf("error (%s, %d)\n", iter->data, iter->len); + // trie_connect(&aho->trie); +} + +void aho_connect_trie(ahocorasick * restrict aho) { trie_connect(&aho->trie); } @@ -88,7 +85,8 @@ int aho_search(ahocorasick * restrict aho, const char *data, int len) { match.len = result->len; match.pos = i - result->len + 1; - if (match.len == 16) counter++; + counter++; + // printf("substitute to %s from ", result->data); if (aho->callback_match) aho->callback_match(aho->callback_arg, &match); } diff --git a/ahocorasick.h b/ahocorasick.h index 183f4ce..908e631 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -21,11 +21,12 @@ typedef struct { void aho_init(ahocorasick * restrict aho); void aho_destroy(ahocorasick * restrict aho); -int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len); +int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len, aho_text * restrict parent); int aho_del_match_text(ahocorasick * restrict aho, const int id); void aho_clear_match_text(ahocorasick * restrict aho); void aho_create_trie(ahocorasick * restrict aho); +void aho_connect_trie(ahocorasick * restrict aho); void aho_clear_trie(ahocorasick * restrict aho); int aho_search(ahocorasick * restrict aho, const char *text, int len); diff --git a/ahotrie.c b/ahotrie.c index 5b72173..320b07c 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -25,7 +25,7 @@ void trie_destroy(aho_trie * restrict t) { trie_delete(t); } -int trie_add(aho_trie * restrict t, aho_text * restrict text) { +int trie_add(aho_trie * restrict t, aho_text * restrict text, aho_text * restrict parent) { aho_node *current = &t->root; for (int i=0; ilen; i++) { @@ -39,7 +39,7 @@ int trie_add(aho_trie * restrict t, aho_text * restrict text) { } current->end = TRUE; - current->output_text = text; + current->output_text = parent; return TRUE; } diff --git a/ahotrie.h b/ahotrie.h index d4fe6e2..c564dec 100644 --- a/ahotrie.h +++ b/ahotrie.h @@ -25,7 +25,7 @@ typedef struct { void trie_init(aho_trie * restrict t); void trie_destroy(aho_trie * restrict t); -int trie_add(aho_trie * restrict t, aho_text * restrict text); +int trie_add(aho_trie * restrict t, aho_text * restrict text, aho_text * restrict parent); void trie_connect(aho_trie * restrict t); void trie_delete(aho_trie * restrict t); aho_text *trie_find(aho_node ** restrict t, const char text); diff --git a/itoi/ahocora.c b/itoi/ahocora.c index d6a95fa..e3fabaa 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -9,11 +9,8 @@ void callback_match_pos(void *arg, aho_match_t *m) { char *text = (char *)arg; - if (m->len >= 17) { - printf("match text: "); - for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); - printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); - } + // for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); + // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); } int bitcount(unsigned long long bits) { @@ -38,16 +35,24 @@ const char *convert(const char *s, const int len, const unsigned long long bitch char *ahocoralike(const char *t, const string_s s[], const int len) { ahocorasick aho; aho_init(&aho); + aho_create_trie(&aho); + + int pre_len = s[0].len; for (int i=0; i 17; ++i); - const string_s *a = &s[i]; + int from, to; + for (from = 0; from Date: Fri, 6 Dec 2019 21:14:12 +0900 Subject: [PATCH 09/37] changed aho_text to string_info --- ahocorasick.c | 68 +++++++++------------------------------------- ahocorasick.h | 16 +++++------ ahotext.c | 14 ---------- ahotext.h | 10 ------- ahotrie.c | 12 +++----- ahotrie.h | 9 +++--- compile.sh | 4 ++- itoi/ahocora.c | 30 ++++++++------------ itoi/ahocora.h | 2 +- itoi/grpwk.c | 2 +- itoi/grpwk.h | 2 +- string_info.h | 4 +-- test_ahocorasick.c | 26 ++++++++++-------- 13 files changed, 63 insertions(+), 136 deletions(-) delete mode 100644 ahotext.c delete mode 100644 ahotext.h diff --git a/ahocorasick.c b/ahocorasick.c index bfa4032..5fbbb62 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -9,78 +9,42 @@ void aho_init(ahocorasick * restrict aho) { memset(aho, 0, sizeof(ahocorasick)); } -void aho_destroy(ahocorasick * restrict aho) { - aho_clear_match_text(aho); - aho_clear_trie(aho); -} - -int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len, aho_text * restrict parent) { - if (aho->text_id == INT_MAX) return -1; +int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { + if (aho->text_id == AHO_SIZE) return FALSE; - aho_text *text = text_init(parent->id, data, len); - if (text == NULL || text->data == NULL) return -1; + text->id = aho->text_id++; + aho->list[text->id] = text; + trie_add(&aho->trie, text, text->str); - trie_add(&aho->trie, text, parent); - free(text->data); - free(text); - - return parent->id; + return TRUE; } -int aho_del_match_text(ahocorasick * restrict aho, const int id) { - for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) { - if (iter->id == id) { - if (iter == aho->head) { - aho->head = iter->next; - free(iter->data); - } else if (iter == aho->tail) { - aho->tail = iter->prev; - free(iter->data); - } else { - iter->prev->next = iter->next; - iter->next->prev = iter->prev; - free(iter->data); - } - free(iter); - aho->text_count--; - return TRUE; - } - } - return FALSE; +int aho_add_similar_text(ahocorasick * restrict aho, const char * restrict data, const string_s * restrict original) { + trie_add(&aho->trie, original, data); + return TRUE; } -void aho_clear_match_text(ahocorasick * restrict aho) { - for (int i=0; itext_id; i++) aho_del_match_text(aho, i); - - aho->text_id = 0; +string_s *aho_search_match_text(ahocorasick * restrict aho, const int id) { + return aho->list[id]; } void aho_create_trie(ahocorasick * restrict aho) { trie_init(&aho->trie); - - // for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) - // if (!trie_add(&aho->trie, iter)) - // printf("error (%s, %d)\n", iter->data, iter->len); - // trie_connect(&aho->trie); } void aho_connect_trie(ahocorasick * restrict aho) { trie_connect(&aho->trie); } -void aho_clear_trie(ahocorasick * restrict aho) { - trie_destroy(&aho->trie); -} - int aho_search(ahocorasick * restrict aho, const char *data, int len) { int counter = 0; aho_node *current = &aho->trie.root; for (int i=0; iid; match.len = result->len; match.pos = i - result->len + 1; @@ -97,9 +61,3 @@ inline void aho_register_match_callback(ahocorasick * restrict aho, void (*callb aho->callback_arg = arg; aho->callback_match = callback_match; } - -void aho_print_match_text(ahocorasick * restrict aho) { - for (aho_text *iter = aho->head; iter != NULL; iter = iter->next) { - printf("id: %d, text:%s, len:%d\n", iter->id, iter->data, iter->len); - } -} diff --git a/ahocorasick.h b/ahocorasick.h index 908e631..ef16267 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -1,7 +1,9 @@ #pragma once #include "ahotrie.h" -#include "ahotext.h" +#include "string_info.h" + +#define AHO_SIZE 45000 typedef struct { int id, pos, len; @@ -9,8 +11,7 @@ typedef struct { typedef struct { int text_id; - aho_text *head, *tail; - int text_count; + string_s *list[AHO_SIZE]; aho_trie trie; @@ -21,9 +22,10 @@ typedef struct { void aho_init(ahocorasick * restrict aho); void aho_destroy(ahocorasick * restrict aho); -int aho_add_match_text(ahocorasick * restrict aho, const char *data, int len, aho_text * restrict parent); -int aho_del_match_text(ahocorasick * restrict aho, const int id); -void aho_clear_match_text(ahocorasick * restrict aho); +int aho_add_match_text(ahocorasick * restrict aho, string_s *text); +int aho_add_similar_text(ahocorasick * restrict aho, const char * restrict data, const string_s * restrict original); + +string_s *aho_search_match_text(ahocorasick * restrict aho, const int id); void aho_create_trie(ahocorasick * restrict aho); void aho_connect_trie(ahocorasick * restrict aho); @@ -32,5 +34,3 @@ void aho_clear_trie(ahocorasick * restrict aho); int aho_search(ahocorasick * restrict aho, const char *text, int len); void aho_register_match_callback(ahocorasick * restrict aho, void (*callback_match)(void* arg, aho_match_t* m), void *arg); - -void aho_print_match_text(ahocorasick * restrict aho); diff --git a/ahotext.c b/ahotext.c deleted file mode 100644 index fe5da03..0000000 --- a/ahotext.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -#include "ahotext.h" - -aho_text *text_init(const int id, char *data, const int len) { - aho_text *text = (aho_text *)malloc(sizeof(aho_text)); - text->id = id; - text->data = data; - text->len = len; - text->prev = NULL; - text->next = NULL; - return text; -} diff --git a/ahotext.h b/ahotext.h deleted file mode 100644 index 604686a..0000000 --- a/ahotext.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -typedef struct _text { - int id; - char *data; - int len; - struct _text *prev, *next; -} aho_text; - -aho_text *text_init(const int id, char *data, const int len); diff --git a/ahotrie.c b/ahotrie.c index 320b07c..9f94dab 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -21,15 +21,11 @@ void trie_init(aho_trie * restrict t) { t->root = *node_init(-1, NULL); } -void trie_destroy(aho_trie * restrict t) { - trie_delete(t); -} - -int trie_add(aho_trie * restrict t, aho_text * restrict text, aho_text * restrict parent) { +int trie_add(aho_trie * restrict t, const string_s * restrict text, const char * restrict similar) { aho_node *current = &t->root; for (int i=0; ilen; i++) { - int char_id = text->data[i] - 'a'; + int char_id = similar[i] - 'a'; if (char_id > 3 || char_id < 0) return FALSE; if (current->child[char_id] == NULL) current->child[char_id] = node_init(char_id, current); @@ -39,7 +35,7 @@ int trie_add(aho_trie * restrict t, aho_text * restrict text, aho_text * restric } current->end = TRUE; - current->output_text = parent; + current->output_text = text; return TRUE; } @@ -116,7 +112,7 @@ int find_node(aho_node ** restrict node, const char text) { return FALSE; } -aho_text *trie_find(aho_node ** restrict node, const char text) { +string_s *trie_find(aho_node ** restrict node, const char text) { while (find_node(node, text) == FALSE) { if (node == NULL || (*node)->parent == NULL) return NULL; *node = (*node)->failure_link; diff --git a/ahotrie.h b/ahotrie.h index c564dec..03298e0 100644 --- a/ahotrie.h +++ b/ahotrie.h @@ -1,6 +1,6 @@ #pragma once -#include "ahotext.h" +#include "string_info.h" #define MAX_NODE 4 #define FALSE 0 @@ -13,7 +13,7 @@ typedef struct _node { struct _node *parent, *child[MAX_NODE]; int end; - aho_text *output_text; + string_s *output_text; struct _node *failure_link, *output_link; } aho_node; @@ -23,11 +23,10 @@ typedef struct { } aho_trie; void trie_init(aho_trie * restrict t); -void trie_destroy(aho_trie * restrict t); -int trie_add(aho_trie * restrict t, aho_text * restrict text, aho_text * restrict parent); +int trie_add(aho_trie * restrict t, const string_s * restrict text, const char * restrict parent); void trie_connect(aho_trie * restrict t); void trie_delete(aho_trie * restrict t); -aho_text *trie_find(aho_node ** restrict t, const char text); +string_s *trie_find(aho_node ** restrict t, const char text); void trie_print(aho_trie * restrict t); diff --git a/compile.sh b/compile.sh index b42c8fc..e086bba 100644 --- a/compile.sh +++ b/compile.sh @@ -13,7 +13,9 @@ usage_exit() { while getopts :hnd:t: OPT do case $OPT in - n) CFLAGS="";; + n) CFLAGS="" + echo "You are running the compiler without -Wall option !!" + ;; d) DIR=$OPTARG;; t) ID=$OPTARG;; h) usage_exit;; diff --git a/itoi/ahocora.c b/itoi/ahocora.c index e3fabaa..06a8fc3 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -22,33 +22,29 @@ int bitcount(unsigned long long bits) { return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); } -const char *convert(const char *s, const int len, const unsigned long long bitcheck) { - char *tmp = (char *)malloc(sizeof(char) * (len + 1)); - for (int i=0; i= 50) - aho_add_match_text(&aho, s, strlen(s)); + // while (~fscanf(fp, "%s", s)) + // if (strlen(s) >= 50) + // aho_add_match_text(&aho, s, strlen(s)); fp = fopen("data/dat0_ref", "r"); fscanf(fp, "%s", s); @@ -96,7 +98,7 @@ int test_input(void) { int main(void) { // test_trie(); // test_ahocora(); - test_input(); + // test_input(); return 0; } From 2858d335853ee3e75617d34b88aa8ae31ccdd277 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 6 Dec 2019 22:38:07 +0900 Subject: [PATCH 10/37] deleted "const" --- ahocorasick.c | 7 ++++--- ahocorasick.h | 6 +++--- ahotrie.c | 6 +++--- ahotrie.h | 4 ++-- example/grpwk.c | 2 +- example/grpwk.h | 2 +- input_win.c | 2 +- itoi/ahocora.c | 29 ++++++++++++++--------------- itoi/ahocora.h | 2 +- itoi/grpwk.c | 2 +- itoi/grpwk.h | 2 +- queue.c | 2 +- queue.h | 2 +- 13 files changed, 34 insertions(+), 34 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 5fbbb62..d7c395f 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -15,16 +15,17 @@ int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { text->id = aho->text_id++; aho->list[text->id] = text; trie_add(&aho->trie, text, text->str); + // if (text->id % 1000 == 0) printf("%d (%d)\n", text->id, text->len); return TRUE; } -int aho_add_similar_text(ahocorasick * restrict aho, const char * restrict data, const string_s * restrict original) { +int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original) { trie_add(&aho->trie, original, data); return TRUE; } -string_s *aho_search_match_text(ahocorasick * restrict aho, const int id) { +string_s *aho_search_match_text(ahocorasick * restrict aho, int id) { return aho->list[id]; } @@ -36,7 +37,7 @@ void aho_connect_trie(ahocorasick * restrict aho) { trie_connect(&aho->trie); } -int aho_search(ahocorasick * restrict aho, const char *data, int len) { +int aho_search(ahocorasick * restrict aho, char *data, int len) { int counter = 0; aho_node *current = &aho->trie.root; diff --git a/ahocorasick.h b/ahocorasick.h index ef16267..6538824 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -23,14 +23,14 @@ void aho_init(ahocorasick * restrict aho); void aho_destroy(ahocorasick * restrict aho); int aho_add_match_text(ahocorasick * restrict aho, string_s *text); -int aho_add_similar_text(ahocorasick * restrict aho, const char * restrict data, const string_s * restrict original); +int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original); -string_s *aho_search_match_text(ahocorasick * restrict aho, const int id); +string_s *aho_search_match_text(ahocorasick * restrict aho, int id); void aho_create_trie(ahocorasick * restrict aho); void aho_connect_trie(ahocorasick * restrict aho); void aho_clear_trie(ahocorasick * restrict aho); -int aho_search(ahocorasick * restrict aho, const char *text, int len); +int aho_search(ahocorasick * restrict aho, char *text, int len); void aho_register_match_callback(ahocorasick * restrict aho, void (*callback_match)(void* arg, aho_match_t* m), void *arg); diff --git a/ahotrie.c b/ahotrie.c index 9f94dab..7fca417 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -21,7 +21,7 @@ void trie_init(aho_trie * restrict t) { t->root = *node_init(-1, NULL); } -int trie_add(aho_trie * restrict t, const string_s * restrict text, const char * restrict similar) { +int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict similar) { aho_node *current = &t->root; for (int i=0; ilen; i++) { @@ -101,7 +101,7 @@ void trie_delete(aho_trie * restrict t) { que_destroy(&que); } -int find_node(aho_node ** restrict node, const char text) { +int find_node(aho_node ** restrict node, char text) { if (*node == NULL) return FALSE; if ((*node)->child[text - 'a'] != NULL && text - 'a' <= 3 && text - 'a' >= 0) { @@ -112,7 +112,7 @@ int find_node(aho_node ** restrict node, const char text) { return FALSE; } -string_s *trie_find(aho_node ** restrict node, const char text) { +string_s *trie_find(aho_node ** restrict node, char text) { while (find_node(node, text) == FALSE) { if (node == NULL || (*node)->parent == NULL) return NULL; *node = (*node)->failure_link; diff --git a/ahotrie.h b/ahotrie.h index 03298e0..8fe4290 100644 --- a/ahotrie.h +++ b/ahotrie.h @@ -24,9 +24,9 @@ typedef struct { void trie_init(aho_trie * restrict t); -int trie_add(aho_trie * restrict t, const string_s * restrict text, const char * restrict parent); +int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict parent); void trie_connect(aho_trie * restrict t); void trie_delete(aho_trie * restrict t); -string_s *trie_find(aho_node ** restrict t, const char text); +string_s *trie_find(aho_node ** restrict t, char text); void trie_print(aho_trie * restrict t); diff --git a/example/grpwk.c b/example/grpwk.c index d22c750..1a9debd 100644 --- a/example/grpwk.c +++ b/example/grpwk.c @@ -3,7 +3,7 @@ #include "grpwk.h" -char *grpwk(const char *t, const string_s s[], int len) { +char *grpwk(char *t, string_s s[], int len) { char *str = (char *)malloc(sizeof(char) * 100); sprintf(str, "I got %d data!", len); diff --git a/example/grpwk.h b/example/grpwk.h index 9308d4f..66454b5 100644 --- a/example/grpwk.h +++ b/example/grpwk.h @@ -2,4 +2,4 @@ #include "../string_info.h" -char *grpwk(const char *t, const string_s s[], int len); \ No newline at end of file +char *grpwk(char *t, string_s s[], int len); \ No newline at end of file diff --git a/input_win.c b/input_win.c index dd2d8b0..01263b4 100644 --- a/input_win.c +++ b/input_win.c @@ -30,7 +30,7 @@ int main(int argc, char **argv) } -int sort_f(const void *a, const void *b) { +int sort_f(void *a, void *b) { return ((string_s *)b)->len - ((string_s *)a)->len; } diff --git a/itoi/ahocora.c b/itoi/ahocora.c index 06a8fc3..1046e98 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -22,27 +22,27 @@ int bitcount(unsigned long long bits) { return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); } -char *ahocoralike(const char *t, string_s s[], const int len) { +void convert(char *tmp, char *s, int len, unsigned long long bitchange) { + for (int i=0; i> i & 1) tmp[i] = 'a'; + else tmp[i] = s[i]; + } + tmp[len] = '\0'; +} + +char *ahocoralike(char *t, string_s s[], int len) { ahocorasick aho; aho_init(&aho); aho_create_trie(&aho); - char tmp[120]; - int pre_len = s[0].len; for (int i=0; isize >= MAX_SIZE) { - // printf("キューの容量がいっぱいです\n"); + printf("キューの容量がいっぱいです\n"); return; } que->data[que->back] = value; diff --git a/queue.h b/queue.h index f1001ec..cd892a7 100644 --- a/queue.h +++ b/queue.h @@ -6,7 +6,7 @@ #define QUEUE_H #define QUE_TYPE aho_node* -#define MAX_SIZE 5000000 +#define MAX_SIZE 8000000 typedef struct { From 58b14cbd2596082f199870ca1a4bae91eb053ad5 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 6 Dec 2019 23:01:40 +0900 Subject: [PATCH 11/37] bug fixed --- input_win.c | 2 +- itoi/ahocora.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/input_win.c b/input_win.c index 01263b4..dd2d8b0 100644 --- a/input_win.c +++ b/input_win.c @@ -30,7 +30,7 @@ int main(int argc, char **argv) } -int sort_f(void *a, void *b) { +int sort_f(const void *a, const void *b) { return ((string_s *)b)->len - ((string_s *)a)->len; } diff --git a/itoi/ahocora.c b/itoi/ahocora.c index 1046e98..db2e770 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -50,10 +50,10 @@ char *ahocoralike(char *t, string_s s[], int len) { aho_connect_trie(&aho); // trie_print(&aho.trie); + aho_register_match_callback(&aho, callback_match_pos, (void *)t); char *ans = (char *)malloc(sizeof(char) * (T_LENGTH + 1)); - aho_register_match_callback(&aho, callback_match_pos, (void *)t); sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); return ans; From 5a6bf9007cfdc77504b6af4785d423b156af0bbb Mon Sep 17 00:00:00 2001 From: pysan3 Date: Mon, 9 Dec 2019 12:28:25 +0900 Subject: [PATCH 12/37] compiler changed --- ahocorasick.c | 1 - ahotrie.c | 6 +++--- analyze.py | 5 ++++- compile.sh | 15 ++++++++------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index d7c395f..5e2dcc9 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "ahocorasick.h" diff --git a/ahotrie.c b/ahotrie.c index 7fca417..b7c9e09 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -104,8 +104,8 @@ void trie_delete(aho_trie * restrict t) { int find_node(aho_node ** restrict node, char text) { if (*node == NULL) return FALSE; - if ((*node)->child[text - 'a'] != NULL && text - 'a' <= 3 && text - 'a' >= 0) { - *node = (*node)->child[text - 'a']; + if ((*node)->child[text] != NULL && text <= 3 && text >= 0) { + *node = (*node)->child[text]; return TRUE; } @@ -113,7 +113,7 @@ int find_node(aho_node ** restrict node, char text) { } string_s *trie_find(aho_node ** restrict node, char text) { - while (find_node(node, text) == FALSE) { + while (find_node(node, text - 'a') == FALSE) { if (node == NULL || (*node)->parent == NULL) return NULL; *node = (*node)->failure_link; } diff --git a/analyze.py b/analyze.py index ab13d32..b237ec2 100644 --- a/analyze.py +++ b/analyze.py @@ -65,9 +65,12 @@ def x_len(): d.setdefault(c, 0) d[c] += 1 c = 0 + import matplotlib.pyplot as plt + plt.plot(sorted(counter[i].keys()), [counter[i][k] for k in sorted(counter[i].keys())]) + plt.show() print_table(counter) -# x_len() +x_len() def t_to_s_rate(): print('t_to_s_rate') diff --git a/compile.sh b/compile.sh index e086bba..ed56ced 100644 --- a/compile.sh +++ b/compile.sh @@ -4,7 +4,7 @@ PROG=grpwk CC=gcc CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" DIR="." -ID=0 +TCASE=0 usage_exit() { echo "Usage: $0 [-n (no warning)] [-d ] [-t ]" @@ -14,10 +14,10 @@ while getopts :hnd:t: OPT do case $OPT in n) CFLAGS="" - echo "You are running the compiler without -Wall option !!" + echo "You are running the compiler withOUT -Wall option!" ;; d) DIR=$OPTARG;; - t) ID=$OPTARG;; + t) TCASE=$OPTARG;; h) usage_exit;; \?) usage_exit;; esac @@ -25,18 +25,19 @@ done shift $(($OPTIND - 1)) FILES=$(find -maxdepth 1 \( -name "*.c" \) \( -not -name "*test*" \)) -TEST=$(find $DIR \( -name "*.c" \) \( -not -name "*test*" \)) +MYFILES=$(find $DIR \( -name "*.c" \) \( -not -name "*test*" \)) -$CC $CFLAGS -o grpwk $FILES $TEST +$CC $CFLAGS -o grpwk $FILES $MYFILES $CC -o distance test_distance.c echo -------------result echo -n "time : " -./grpwk data/dat${ID}_in result -./distance result data/dat${ID}_ref +./grpwk data/dat${TCASE}_in result +./distance result data/dat${TCASE}_ref rm distance rm grpwk +echo echo -------------output cat result From a84ce0a60dcd9fff21fa3cef10fa6591647f4e49 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Tue, 10 Dec 2019 18:23:12 +0900 Subject: [PATCH 13/37] test_ahocorasick.c fixed --- a.out | Bin 0 -> 18008 bytes ahocorasick.c | 1 + ahocorasick.h | 1 + compile.sh | 6 +++--- itoi/ahocora.c | 17 ++++++++++++++--- test_ahocorasick.c | 38 +++++++++++++++++++++++--------------- test_distance.c | 9 ++++++--- 7 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 a.out diff --git a/a.out b/a.out new file mode 100644 index 0000000000000000000000000000000000000000..34a935a74b1de13cf6c1e48f96982ceb44644d54 GIT binary patch literal 18008 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 literal 0 HcmV?d00001 diff --git a/ahocorasick.c b/ahocorasick.c index 5e2dcc9..2a85bcf 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -48,6 +48,7 @@ int aho_search(ahocorasick * restrict aho, char *data, int len) { match.id = result->id; match.len = result->len; match.pos = i - result->len + 1; + match.s = result->str; counter++; // printf("substitute to %s from ", result->data); diff --git a/ahocorasick.h b/ahocorasick.h index 6538824..31cbfe5 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -7,6 +7,7 @@ typedef struct { int id, pos, len; + char *s; } aho_match_t; typedef struct { diff --git a/compile.sh b/compile.sh index ed56ced..1a479d3 100644 --- a/compile.sh +++ b/compile.sh @@ -38,6 +38,6 @@ echo -n "time : " rm distance rm grpwk -echo -echo -------------output -cat result +# echo +# echo -------------output +# cat result diff --git a/itoi/ahocora.c b/itoi/ahocora.c index db2e770..ca0f3b9 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -11,6 +11,7 @@ void callback_match_pos(void *arg, aho_match_t *m) { // for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); + for (int i=0; ilen; i++) if (text[m->pos+i] == 0) text[m->pos+i] = m->s[i]; } int bitcount(unsigned long long bits) { @@ -50,11 +51,21 @@ char *ahocoralike(char *t, string_s s[], int len) { aho_connect_trie(&aho); // trie_print(&aho.trie); - aho_register_match_callback(&aho, callback_match_pos, (void *)t); - char *ans = (char *)malloc(sizeof(char) * (T_LENGTH + 1)); + char *ans = (char *)calloc(T_LENGTH + 1, sizeof(char)); + aho_register_match_callback(&aho, callback_match_pos, (void *)ans); - sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); + // sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); + aho_search(&aho, t, T_LENGTH); + + int counter = 0; + for (int i=0; i +#include #include +#include "string_info.h" #include "ahocorasick.h" int test_trie(void) { @@ -23,18 +25,19 @@ int test_trie(void) { }; string_s text[100]; - aho_trie *t; - trie_init(t); + aho_trie t; + trie_init(&t); - for (int i=0; iid, m->pos, m->len); } +string_s *new(char *s) { + string_s *n = (string_s *)malloc(sizeof(string_s)); + n->len = strlen(s); + strcpy(n->str, s); + return n; +} + int test_ahocora(void) { ahocorasick aho; aho_init(&aho); + aho_create_trie(&aho); + + aho_add_match_text(&aho, new("ab")); + aho_add_match_text(&aho, new("abc")); + aho_add_match_text(&aho, new("ca")); - // aho_add_match_text(&aho, "ab", strlen("ab")); - // aho_add_match_text(&aho, "abc", strlen("abc")); - // aho_add_match_text(&aho, "ca", strlen("ca")); + aho_connect_trie(&aho); char test[] = "abcabcabcab"; - aho_create_trie(&aho); aho_register_match_callback(&aho, callback_match_pos, (void *)test); trie_print(&aho.trie); @@ -66,8 +78,6 @@ int test_ahocora(void) { printf("try: %s\n", test); printf("total match: %d\n", aho_search(&aho, test, strlen(test))); - aho_destroy(&aho); - return 0; } @@ -90,15 +100,13 @@ int test_input(void) { printf("total match: %d\n", aho_search(&aho, s, strlen(s))); - aho_destroy(&aho); - return 0; } int main(void) { // test_trie(); // test_ahocora(); - // test_input(); + test_input(); return 0; } diff --git a/test_distance.c b/test_distance.c index 3805c27..31ec80d 100644 --- a/test_distance.c +++ b/test_distance.c @@ -13,11 +13,14 @@ int main(int argc, char *argv[]) { fscanf(fp_in, "%s", in); fscanf(fp_out, "%s", out); - int counter = 0; - for (int i=0; i Date: Tue, 10 Dec 2019 20:59:38 +0900 Subject: [PATCH 14/37] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=80=81=E8=AA=AC=E6=98=8E=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ahocorasick.c | 15 +++++++++++++++ ahotrie.c | 10 ++++++++++ compile.sh | 37 +++++++++++++++++++++++-------------- itoi/ahocora.c | 33 ++++++++++++++++++++++----------- itoi/grpwk.c | 1 + test_ahocorasick.c | 22 ++++++++++++++-------- 6 files changed, 85 insertions(+), 33 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 2a85bcf..159858d 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -4,10 +4,14 @@ #include "ahocorasick.h" +// ahocorasick型の変数の初期化 void aho_init(ahocorasick * restrict aho) { memset(aho, 0, sizeof(ahocorasick)); } +/** キー(string_s *s_i)を木に追加、引数のstring_s->idを変更 + * return 挿入成功:TRUE、容量を超過:FALSE + */ int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { if (aho->text_id == AHO_SIZE) return FALSE; @@ -19,23 +23,33 @@ int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { return TRUE; } +/** 曖昧検索用文字列挿入用(木に挿入する文字列と探索成功時の返す文字列が違う場合に使用) + * 木に挿入する文字列をメモリに保存せずに済む + * data:曖昧の文字列、original:虫食い前のデータ + */ int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original) { trie_add(&aho->trie, original, data); return TRUE; } +// idに相当するstring_sを返す string_s *aho_search_match_text(ahocorasick * restrict aho, int id) { return aho->list[id]; } +// トライ木を生成 void aho_create_trie(ahocorasick * restrict aho) { trie_init(&aho->trie); } +// トライ木からアホコラを作る void aho_connect_trie(ahocorasick * restrict aho) { trie_connect(&aho->trie); } +/** 検索関数(data:t'、len:len(t')) + * return マッチしたキーの数 + */ int aho_search(ahocorasick * restrict aho, char *data, int len) { int counter = 0; aho_node *current = &aho->trie.root; @@ -58,6 +72,7 @@ int aho_search(ahocorasick * restrict aho, char *data, int len) { return counter; } +// 探索が成功した際に実行される関数を設定する関数 inline void aho_register_match_callback(ahocorasick * restrict aho, void (*callback_match)(void *arg, aho_match_t *), void *arg) { aho->callback_arg = arg; aho->callback_match = callback_match; diff --git a/ahotrie.c b/ahotrie.c index b7c9e09..01d5d39 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -5,6 +5,7 @@ #include "ahotrie.h" #include "queue.h" +// 新しいノードを生成 aho_node *node_init(int data, aho_node * restrict parent) { aho_node *node = (aho_node *)malloc(sizeof(aho_node)); memset(node, 0, sizeof(aho_node)); @@ -15,12 +16,18 @@ aho_node *node_init(int data, aho_node * restrict parent) { return node; } +// トライ木を初期化 void trie_init(aho_trie * restrict t) { if (t == NULL) t = (aho_trie *)malloc(sizeof(aho_trie)); memset(t, 0, sizeof(aho_trie)); t->root = *node_init(-1, NULL); } +/** トライ木に文字列を挿入 + * string_s *text: ゴール + * char *similar: 入力文字列 + * - aho_add_match_textのときは text->str == similar + **/ int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict similar) { aho_node *current = &t->root; @@ -62,6 +69,7 @@ int connect_link(aho_node *p, aho_node *q) { return FALSE; } +// トライ木をアホコラに合わせて再構成 void trie_connect(aho_trie * restrict t) { queue que; que_init(&que); @@ -112,6 +120,7 @@ int find_node(aho_node ** restrict node, char text) { return FALSE; } +// textが木に含まれる場合、終端に設定したstring_sを返す。含まれない場合はNULL。 string_s *trie_find(aho_node ** restrict node, char text) { while (find_node(node, text - 'a') == FALSE) { if (node == NULL || (*node)->parent == NULL) return NULL; @@ -124,6 +133,7 @@ string_s *trie_find(aho_node ** restrict node, char text) { return NULL; } +// トライ木を表示。ノードが多くなってくると使い物にならない。 void trie_print(aho_trie * restrict t) { queue que; que_init(&que); diff --git a/compile.sh b/compile.sh index 1a479d3..d553976 100644 --- a/compile.sh +++ b/compile.sh @@ -1,43 +1,52 @@ #!/bin/bash -PROG=grpwk -CC=gcc -CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" -DIR="." -TCASE=0 - +# 各種設定(初期設定) +PROG=grpwk # 実行ファイル名 +CC=gcc # コンパイラ +CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" # ワーニング +DIR="example" # 自分で作ったgrpwk.cがあるディレクトリ +TCASE=0 # dat${TCASE}_inを参照(テストケースの選択) + +# 使い方の説明 usage_exit() { echo "Usage: $0 [-n (no warning)] [-d ] [-t ]" } +# コマンドラインオプションを設定 while getopts :hnd:t: OPT do case $OPT in - n) CFLAGS="" + n) CFLAGS="" # コンパイルをワーニングなしで実行 echo "You are running the compiler withOUT -Wall option!" ;; - d) DIR=$OPTARG;; - t) TCASE=$OPTARG;; - h) usage_exit;; - \?) usage_exit;; + d) DIR=$OPTARG;; # grpwk.cのあるディレクトリの設定(トップディレクトリとこのディレクトリしかコンパイルされないためファイル構成には注意) + t) TCASE=$OPTARG;; # テストケースの設定:0-4 + h) usage_exit;; # ヘルプ + \?) usage_exit;; # 例外処理 esac done -shift $(($OPTIND - 1)) +shift $(($OPTIND - 1)) # コマンドラインオプションで用いたものたちをargvから消去 -FILES=$(find -maxdepth 1 \( -name "*.c" \) \( -not -name "*test*" \)) -MYFILES=$(find $DIR \( -name "*.c" \) \( -not -name "*test*" \)) +# ファイルを探索:名前にtestを含まない*.cなものをすべて取ってくる +FILES=$(find -maxdepth 1 \( -name "*.c" \) \( -not -name "*test*" \)) # トップディレクトリ +MYFILES=$(find $DIR \( -name "*.c" \) \( -not -name "*test*" \)) # -dで設定されたディレクトリ +# コンパイル $CC $CFLAGS -o grpwk $FILES $MYFILES $CC -o distance test_distance.c +# 実行 echo -------------result echo -n "time : " ./grpwk data/dat${TCASE}_in result ./distance result data/dat${TCASE}_ref +# 実行ファイルの消去 rm distance rm grpwk +# 出力された文字列の表示(デバッグ等に使用) +# 一般的には長すぎてターミナルが重くなってしまうためコメントアウト # echo # echo -------------output # cat result diff --git a/itoi/ahocora.c b/itoi/ahocora.c index ca0f3b9..f3516ae 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -11,9 +11,13 @@ void callback_match_pos(void *arg, aho_match_t *m) { // for (int i=m->pos; ipos+m->len; i++) printf("%c", text[i]); // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); + + /* もしarg(下で言うans)の該当部分が0だったときに文字を代入 */ + /* TODO: まだ正確なやり方を実装していないため、暫定的に */ for (int i=0; ilen; i++) if (text[m->pos+i] == 0) text[m->pos+i] = m->s[i]; } +// 入力されたintの中で何個のビットが立っているかを返す int bitcount(unsigned long long bits) { bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); bits = (bits & 0x3333333333333333) + (bits >> 2 & 0x3333333333333333); @@ -23,6 +27,7 @@ int bitcount(unsigned long long bits) { return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); } +// bitchangeにおいて立っているビットの場所の文字を'a'に置換する void convert(char *tmp, char *s, int len, unsigned long long bitchange) { for (int i=0; i> i & 1) tmp[i] = 'a'; @@ -31,41 +36,47 @@ void convert(char *tmp, char *s, int len, unsigned long long bitchange) { tmp[len] = '\0'; } +// アホコラを使用したあいまい検索の関数 char *ahocoralike(char *t, string_s s[], int len) { + /* おまじない */ ahocorasick aho; aho_init(&aho); aho_create_trie(&aho); + char tmp[120]; for (int i=0; iid, m->pos, m->len); } +// char *sからそれに相当するstring_sを生成 string_s *new(char *s) { string_s *n = (string_s *)malloc(sizeof(string_s)); n->len = strlen(s); @@ -61,16 +62,20 @@ string_s *new(char *s) { int test_ahocora(void) { ahocorasick aho; - aho_init(&aho); - aho_create_trie(&aho); + aho_init(&aho); /* aho初期化 */ + aho_create_trie(&aho); /* トライ木初期化 */ + /* 上二つの関数は必ず実行!! */ + /* キーを木に追加 */ aho_add_match_text(&aho, new("ab")); aho_add_match_text(&aho, new("abc")); aho_add_match_text(&aho, new("ca")); + /* アホコラ用にトライ木を再構成 */ aho_connect_trie(&aho); char test[] = "abcabcabcab"; + /* 探索成功時に実行される関数をセットする */ aho_register_match_callback(&aho, callback_match_pos, (void *)test); trie_print(&aho.trie); @@ -84,6 +89,7 @@ int test_ahocora(void) { int test_input(void) { ahocorasick aho; aho_init(&aho); + aho_create_trie(&aho); char s[500000]; FILE *fp = fopen("data/dat0_in", "r"); @@ -95,7 +101,7 @@ int test_input(void) { fp = fopen("data/dat0_ref", "r"); fscanf(fp, "%s", s); - aho_create_trie(&aho); + aho_connect_trie(&aho); aho_register_match_callback(&aho, callback_match_pos, (void *)s); printf("total match: %d\n", aho_search(&aho, s, strlen(s))); @@ -106,7 +112,7 @@ int test_input(void) { int main(void) { // test_trie(); // test_ahocora(); - test_input(); + // test_input(); return 0; } From d6f2994f77fc30f9d7c2ee7e9d2459ea2a1a0063 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Tue, 10 Dec 2019 21:07:06 +0900 Subject: [PATCH 15/37] small changes --- compile.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compile.sh b/compile.sh index d553976..6fcafda 100644 --- a/compile.sh +++ b/compile.sh @@ -1,5 +1,8 @@ #!/bin/bash +# 使用例 +# ./compile.sh -d example -t 0 -n + # 各種設定(初期設定) PROG=grpwk # 実行ファイル名 CC=gcc # コンパイラ From 75a0500bd4ef515e89985c7c2073929e65be26ee Mon Sep 17 00:00:00 2001 From: pysan3 Date: Tue, 10 Dec 2019 21:12:08 +0900 Subject: [PATCH 16/37] small bug fixed --- compile.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compile.sh b/compile.sh index 6fcafda..044df2f 100644 --- a/compile.sh +++ b/compile.sh @@ -53,3 +53,5 @@ rm grpwk # echo # echo -------------output # cat result + +echo "done" From e392cbfaba427c8e938baa929f86f775b94e1301 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 15 Dec 2019 23:26:46 +0900 Subject: [PATCH 17/37] count options --- ahocorasick.c | 13 +------------ ahocorasick.h | 5 ----- input_win.c | 2 ++ itoi/ahocora.c | 18 +++++++++++++++--- itoi/grpwk.h | 2 +- test_distance.c | 3 ++- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 159858d..f70dd5c 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -9,17 +9,11 @@ void aho_init(ahocorasick * restrict aho) { memset(aho, 0, sizeof(ahocorasick)); } -/** キー(string_s *s_i)を木に追加、引数のstring_s->idを変更 +/** キー(string_s *s_i)を木に追加 * return 挿入成功:TRUE、容量を超過:FALSE */ int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { - if (aho->text_id == AHO_SIZE) return FALSE; - - text->id = aho->text_id++; - aho->list[text->id] = text; trie_add(&aho->trie, text, text->str); - // if (text->id % 1000 == 0) printf("%d (%d)\n", text->id, text->len); - return TRUE; } @@ -32,11 +26,6 @@ int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, strin return TRUE; } -// idに相当するstring_sを返す -string_s *aho_search_match_text(ahocorasick * restrict aho, int id) { - return aho->list[id]; -} - // トライ木を生成 void aho_create_trie(ahocorasick * restrict aho) { trie_init(&aho->trie); diff --git a/ahocorasick.h b/ahocorasick.h index 31cbfe5..0c36093 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -11,9 +11,6 @@ typedef struct { } aho_match_t; typedef struct { - int text_id; - string_s *list[AHO_SIZE]; - aho_trie trie; void (*callback_match)(void *arg, aho_match_t *m); @@ -26,8 +23,6 @@ void aho_destroy(ahocorasick * restrict aho); int aho_add_match_text(ahocorasick * restrict aho, string_s *text); int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original); -string_s *aho_search_match_text(ahocorasick * restrict aho, int id); - void aho_create_trie(ahocorasick * restrict aho); void aho_connect_trie(ahocorasick * restrict aho); void aho_clear_trie(ahocorasick * restrict aho); diff --git a/input_win.c b/input_win.c index dd2d8b0..3047a5d 100644 --- a/input_win.c +++ b/input_win.c @@ -54,6 +54,8 @@ int main_prg(int argc, char **argv) for (; fscanf(fp_in, "%s", s[counter].str) != EOF; ++counter) s[counter].len = strlen(s[counter].str); qsort(s, counter, sizeof(string_s), sort_f); + for (int i=0; ipos; ipos+m->len; i++) printf("%c", text[i]); @@ -17,6 +17,11 @@ void callback_match_pos(void *arg, aho_match_t *m) { for (int i=0; ilen; i++) if (text[m->pos+i] == 0) text[m->pos+i] = m->s[i]; } +void callback_count_options(void *arg, aho_match_t *m) { + int *tmp = (int *)arg; + tmp[m->id] += 1; +} + // 入力されたintの中で何個のビットが立っているかを返す int bitcount(unsigned long long bits) { bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); @@ -50,7 +55,7 @@ char *ahocoralike(char *t, string_s s[], int len) { /* s[i]が虫食いされて生じうる文字列を木に追加 */ int max_bit = s[i].len / 2; /* 虫食いされる個数は文字列長の半分以下に限定 */ - unsigned long long until = ((unsigned long long)1< Date: Mon, 16 Dec 2019 01:57:22 +0900 Subject: [PATCH 18/37] testing... --- a.out | Bin 18008 -> 0 bytes ahocorasick.c | 1 + ahocorasick.h | 1 + ahotrie.c | 9 ++++----- itoi/ahocora.c | 2 +- test_ahocorasick.c | 5 +++-- 6 files changed, 10 insertions(+), 8 deletions(-) delete mode 100644 a.out diff --git a/a.out b/a.out deleted file mode 100644 index 34a935a74b1de13cf6c1e48f96982ceb44644d54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18008 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 diff --git a/ahocorasick.c b/ahocorasick.c index f70dd5c..8dfe1ac 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -52,6 +52,7 @@ int aho_search(ahocorasick * restrict aho, char *data, int len) { match.len = result->len; match.pos = i - result->len + 1; match.s = result->str; + match.text = result; counter++; // printf("substitute to %s from ", result->data); diff --git a/ahocorasick.h b/ahocorasick.h index 0c36093..68f8da4 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -8,6 +8,7 @@ typedef struct { int id, pos, len; char *s; + string_s *text; } aho_match_t; typedef struct { diff --git a/ahotrie.c b/ahotrie.c index 01d5d39..7319cbf 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -82,9 +82,9 @@ void trie_connect(aho_trie * restrict t) { for (int i=0; ichild[i] == NULL) continue; - aho_node *tmp = node, *child = node->child[i]; - que_push(&que, child); + que_push(&que, node->child[i]); + aho_node *tmp = node, *child = node->child[i]; while (connect_link(tmp, child) == FALSE) tmp = tmp->failure_link; } } @@ -128,9 +128,8 @@ string_s *trie_find(aho_node ** restrict node, char text) { } if ((*node)->end) return (*node)->output_text; - if ((*node)->output_link) return (*node)->output_link->output_text; - - return NULL; + else if ((*node)->output_link) return (*node)->output_link->output_text; + else return NULL; } // トライ木を表示。ノードが多くなってくると使い物にならない。 diff --git a/itoi/ahocora.c b/itoi/ahocora.c index bc649cb..9a83e02 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -84,7 +84,7 @@ char *ahocoralike(char *t, string_s s[], int len) { for (int i=0; i Date: Fri, 20 Dec 2019 14:03:12 +0900 Subject: [PATCH 19/37] small changes --- ahotrie.c | 2 +- itoi/ahocora.c | 17 +++++++++-------- itoi/grpwk.h | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ahotrie.c b/ahotrie.c index 7319cbf..83d5270 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -129,7 +129,7 @@ string_s *trie_find(aho_node ** restrict node, char text) { if ((*node)->end) return (*node)->output_text; else if ((*node)->output_link) return (*node)->output_link->output_text; - else return NULL; + else NULL; } // トライ木を表示。ノードが多くなってくると使い物にならない。 diff --git a/itoi/ahocora.c b/itoi/ahocora.c index 9a83e02..93aca03 100644 --- a/itoi/ahocora.c +++ b/itoi/ahocora.c @@ -14,7 +14,7 @@ void callback_substitute_zeros(void *arg, aho_match_t *m) { /* もしarg(下で言うans)の該当部分が0だったときに文字を代入 */ /* TODO: まだ正確なやり方を実装していないため、暫定的に */ - for (int i=0; ilen; i++) if (text[m->pos+i] == 0) text[m->pos+i] = m->s[i]; + for (int i=0; ilen; i++) if (text[m->pos+i] == 'x') text[m->pos+i] = m->s[i]; } void callback_count_options(void *arg, aho_match_t *m) { @@ -68,23 +68,24 @@ char *ahocoralike(char *t, string_s s[], int len) { // trie_print(&aho.trie); char *ans = (char *)calloc(T_LENGTH + 1, sizeof(char)); /* 変換後を保存する文字列 */ - // aho_register_match_callback(&aho, callback_substitute_zeros, (void *)ans); /* 探索成功時に実行される関数を定義。関数は上を参照 */ + strcpy(ans, t); + aho_register_match_callback(&aho, callback_substitute_zeros, (void *)ans); /* 探索成功時に実行される関数を定義。関数は上を参照 */ - int count[41000] = {0}; - aho_register_match_callback(&aho, callback_count_options, (void *)count); + // int count[41000] = {0}; + // aho_register_match_callback(&aho, callback_count_options, (void *)count); // sprintf(ans, "total match: %d\n", aho_search(&aho, t, T_LENGTH)); aho_search(&aho, t, T_LENGTH); - for (int i=0; i Date: Sat, 21 Dec 2019 01:40:02 +0900 Subject: [PATCH 20/37] aho_search to linked list --- ahocorasick.c | 41 ++++++----- ahocorasick.h | 34 +++++---- ahotrie.c | 34 +++++---- ahotrie.h | 16 +++-- compile.sh | 10 +-- input_win.c | 2 +- itoi/ahocora.c | 59 ++++++++------- itoi/ahocora.h | 3 +- itoi/grpwk.c | 8 ++- itoi/grpwk.h | 4 +- linked_list.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++ linked_list.h | 26 +++++++ 12 files changed, 335 insertions(+), 93 deletions(-) create mode 100644 linked_list.c create mode 100644 linked_list.h diff --git a/ahocorasick.c b/ahocorasick.c index 8dfe1ac..0240c63 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -5,14 +5,19 @@ #include "ahocorasick.h" // ahocorasick型の変数の初期化 -void aho_init(ahocorasick * restrict aho) { +void aho_init(ahocorasick * aho, string_s *s) { memset(aho, 0, sizeof(ahocorasick)); + aho->s = s; +} + +void aho_destroy(ahocorasick * aho) { + aho_clear_trie(aho); } /** キー(string_s *s_i)を木に追加 * return 挿入成功:TRUE、容量を超過:FALSE */ -int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { +int aho_add_match_text(ahocorasick * aho, string_s *text) { trie_add(&aho->trie, text, text->str); return TRUE; } @@ -21,49 +26,49 @@ int aho_add_match_text(ahocorasick * restrict aho, string_s *text) { * 木に挿入する文字列をメモリに保存せずに済む * data:曖昧の文字列、original:虫食い前のデータ */ -int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original) { +int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original) { trie_add(&aho->trie, original, data); return TRUE; } // トライ木を生成 -void aho_create_trie(ahocorasick * restrict aho) { +void aho_create_trie(ahocorasick * aho) { trie_init(&aho->trie); } // トライ木からアホコラを作る -void aho_connect_trie(ahocorasick * restrict aho) { +void aho_connect_trie(ahocorasick * aho) { trie_connect(&aho->trie); } +void aho_clear_trie(ahocorasick * aho) { + trie_destroy(&aho->trie); +} + /** 検索関数(data:t'、len:len(t')) * return マッチしたキーの数 */ -int aho_search(ahocorasick * restrict aho, char *data, int len) { +int aho_search(ahocorasick * aho, char *data, int len) { int counter = 0; aho_node *current = &aho->trie.root; for (int i=0; iid; - match.len = result->len; - match.pos = i - result->len + 1; - match.s = result->str; - match.text = result; - counter++; // printf("substitute to %s from ", result->data); - if (aho->callback_match) aho->callback_match(aho->callback_arg, &match); + aho->callback_match(aho, result, i); } return counter; } // 探索が成功した際に実行される関数を設定する関数 -inline void aho_register_match_callback(ahocorasick * restrict aho, void (*callback_match)(void *arg, aho_match_t *), void *arg) { - aho->callback_arg = arg; +inline void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)) { aho->callback_match = callback_match; } + +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, int *s_count) { + aho->t_opt = t_opt; + aho->s_count = s_count; +} diff --git a/ahocorasick.h b/ahocorasick.h index 68f8da4..815c031 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -2,32 +2,30 @@ #include "ahotrie.h" #include "string_info.h" +#include "linked_list.h" #define AHO_SIZE 45000 -typedef struct { - int id, pos, len; - char *s; - string_s *text; -} aho_match_t; - -typedef struct { +typedef struct _ahocorasick { aho_trie trie; + string_s *s; - void (*callback_match)(void *arg, aho_match_t *m); - void *callback_arg; + void (*callback_match)(struct _ahocorasick * aho, linked_list* l, int pos); + linked_list *t_opt; + int *s_count; } ahocorasick; -void aho_init(ahocorasick * restrict aho); -void aho_destroy(ahocorasick * restrict aho); +void aho_init(ahocorasick * aho, string_s *s); +void aho_destroy(ahocorasick * aho); -int aho_add_match_text(ahocorasick * restrict aho, string_s *text); -int aho_add_similar_text(ahocorasick * restrict aho, char * restrict data, string_s * restrict original); +int aho_add_match_text(ahocorasick * aho, string_s *text); +int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original); -void aho_create_trie(ahocorasick * restrict aho); -void aho_connect_trie(ahocorasick * restrict aho); -void aho_clear_trie(ahocorasick * restrict aho); +void aho_create_trie(ahocorasick * aho); +void aho_connect_trie(ahocorasick * aho); +void aho_clear_trie(ahocorasick * aho); -int aho_search(ahocorasick * restrict aho, char *text, int len); +int aho_search(ahocorasick * aho, char *text, int len); -void aho_register_match_callback(ahocorasick * restrict aho, void (*callback_match)(void* arg, aho_match_t* m), void *arg); +void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)); +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, int *s_count); diff --git a/ahotrie.c b/ahotrie.c index 83d5270..3b540fe 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -6,29 +6,35 @@ #include "queue.h" // 新しいノードを生成 -aho_node *node_init(int data, aho_node * restrict parent) { +aho_node *node_init(int data, aho_node * parent) { aho_node *node = (aho_node *)malloc(sizeof(aho_node)); memset(node, 0, sizeof(aho_node)); node->data = data; node->parent = parent; node->ref_count = 1; node->end = FALSE; + linked_init(&node->output_list); return node; } // トライ木を初期化 -void trie_init(aho_trie * restrict t) { +void trie_init(aho_trie * t) { if (t == NULL) t = (aho_trie *)malloc(sizeof(aho_trie)); memset(t, 0, sizeof(aho_trie)); t->root = *node_init(-1, NULL); } +// トライ木消去 +void trie_destroy(aho_trie * t) { + trie_delete(t); +} + /** トライ木に文字列を挿入 * string_s *text: ゴール * char *similar: 入力文字列 * - aho_add_match_textのときは text->str == similar **/ -int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict similar) { +int trie_add(aho_trie * t, string_s * text, char * similar) { aho_node *current = &t->root; for (int i=0; ilen; i++) { @@ -42,7 +48,7 @@ int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict si } current->end = TRUE; - current->output_text = text; + linked_push_int(¤t->output_list, text->id); return TRUE; } @@ -70,7 +76,7 @@ int connect_link(aho_node *p, aho_node *q) { } // トライ木をアホコラに合わせて再構成 -void trie_connect(aho_trie * restrict t) { +void trie_connect(aho_trie * t) { queue que; que_init(&que); que_push(&que, &t->root); @@ -92,7 +98,7 @@ void trie_connect(aho_trie * restrict t) { que_destroy(&que); } -void trie_delete(aho_trie * restrict t) { +void trie_delete(aho_trie * t) { queue que; que_init(&que); que_push(&que, &t->root); @@ -102,14 +108,16 @@ void trie_delete(aho_trie * restrict t) { if (node == NULL) break; for (int i=0; ichild[i] != NULL) que_push(&que, node->child[i]); + linked_destroy(&node->output_list); if (node->parent == NULL) continue; + free(node); } que_destroy(&que); } -int find_node(aho_node ** restrict node, char text) { +int find_node(aho_node ** node, int text) { if (*node == NULL) return FALSE; if ((*node)->child[text] != NULL && text <= 3 && text >= 0) { @@ -120,20 +128,20 @@ int find_node(aho_node ** restrict node, char text) { return FALSE; } -// textが木に含まれる場合、終端に設定したstring_sを返す。含まれない場合はNULL。 -string_s *trie_find(aho_node ** restrict node, char text) { +// textが木に含まれる場合、終端に設定したlinked_listを返す。含まれない場合はNULL。 +linked_list *trie_find(aho_node ** node, char text) { while (find_node(node, text - 'a') == FALSE) { if (node == NULL || (*node)->parent == NULL) return NULL; *node = (*node)->failure_link; } - if ((*node)->end) return (*node)->output_text; - else if ((*node)->output_link) return (*node)->output_link->output_text; - else NULL; + if ((*node)->end) return &(*node)->output_list; + else if ((*node)->output_link) return &(*node)->output_link->output_list; + else return NULL; } // トライ木を表示。ノードが多くなってくると使い物にならない。 -void trie_print(aho_trie * restrict t) { +void trie_print(aho_trie * t) { queue que; que_init(&que); que_push(&que, &t->root); diff --git a/ahotrie.h b/ahotrie.h index 8fe4290..b494ad5 100644 --- a/ahotrie.h +++ b/ahotrie.h @@ -1,6 +1,7 @@ #pragma once #include "string_info.h" +#include "linked_list.h" #define MAX_NODE 4 #define FALSE 0 @@ -13,7 +14,7 @@ typedef struct _node { struct _node *parent, *child[MAX_NODE]; int end; - string_s *output_text; + linked_list output_list; struct _node *failure_link, *output_link; } aho_node; @@ -22,11 +23,12 @@ typedef struct { aho_node root; } aho_trie; -void trie_init(aho_trie * restrict t); +void trie_init(aho_trie * t); +void trie_destroy(aho_trie * t); -int trie_add(aho_trie * restrict t, string_s * restrict text, char * restrict parent); -void trie_connect(aho_trie * restrict t); -void trie_delete(aho_trie * restrict t); -string_s *trie_find(aho_node ** restrict t, char text); +int trie_add(aho_trie * t, string_s * text, char * parent); +void trie_connect(aho_trie * t); +void trie_delete(aho_trie * t); +linked_list *trie_find(aho_node ** t, char text); -void trie_print(aho_trie * restrict t); +void trie_print(aho_trie * t); diff --git a/compile.sh b/compile.sh index 044df2f..d92223b 100644 --- a/compile.sh +++ b/compile.sh @@ -1,25 +1,25 @@ #!/bin/bash # 使用例 -# ./compile.sh -d example -t 0 -n +# ./compile.sh -d example -t 0 -f # 各種設定(初期設定) PROG=grpwk # 実行ファイル名 CC=gcc # コンパイラ -CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow" # ワーニング +CFLAGS="-W -Wall -Wextra -Wconversion -Wshadow -O0" # ワーニング DIR="example" # 自分で作ったgrpwk.cがあるディレクトリ TCASE=0 # dat${TCASE}_inを参照(テストケースの選択) # 使い方の説明 usage_exit() { - echo "Usage: $0 [-n (no warning)] [-d ] [-t ]" + echo "Usage: $0 [-f (-fast: no warning)] [-d ] [-t ]" } # コマンドラインオプションを設定 -while getopts :hnd:t: OPT +while getopts :hfd:t:f OPT do case $OPT in - n) CFLAGS="" # コンパイルをワーニングなしで実行 + f) CFLAGS="-fast" # コンパイルをワーニングなしで実行 echo "You are running the compiler withOUT -Wall option!" ;; d) DIR=$OPTARG;; # grpwk.cのあるディレクトリの設定(トップディレクトリとこのディレクトリしかコンパイルされないためファイル構成には注意) diff --git a/input_win.c b/input_win.c index 3047a5d..ebd1afc 100644 --- a/input_win.c +++ b/input_win.c @@ -47,7 +47,7 @@ int main_prg(int argc, char **argv) // input t fscanf(fp_in, "%s", t); - for (int i=0; ipos; ipos+m->len; i++) printf("%c", text[i]); - // printf(" (match id: %d position: %d length: %d)\n", m->id, m->pos, m->len); - - /* もしarg(下で言うans)の該当部分が0だったときに文字を代入 */ - /* TODO: まだ正確なやり方を実装していないため、暫定的に */ - for (int i=0; ilen; i++) if (text[m->pos+i] == 'x') text[m->pos+i] = m->s[i]; -} - -void callback_count_options(void *arg, aho_match_t *m) { - int *tmp = (int *)arg; - tmp[m->id] += 1; +void callback_add2linked_list(ahocorasick * aho, linked_list *l, int pos) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter = iter->next) { + // s_count[i]++ + aho->s_count[iter->data]++; + + string_s text = aho->s[iter->data]; + // t_opt[i].append(i, place) + for (int i=0; it_opt[pos-text.len+1 + i], iter->data, i); + } + } } // 入力されたintの中で何個のビットが立っているかを返す @@ -42,15 +40,15 @@ void convert(char *tmp, char *s, int len, unsigned long long bitchange) { } // アホコラを使用したあいまい検索の関数 -char *ahocoralike(char *t, string_s s[], int len) { +char *ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count) { /* おまじない */ ahocorasick aho; - aho_init(&aho); + aho_init(&aho, s); aho_create_trie(&aho); char tmp[120]; - for (int i=0; i 100) printf("%d: %d, %s(%d)\n", s[i].id, s_count[s[i].id], s[i].str, s[i].len); + // } + // for (int i=0; i +#include +#include + +#include "linked_list.h" + +linked_node *linked_node_init(int data) { + linked_node *tmp = (linked_node *)malloc(sizeof(linked_node)); + tmp->data = data; + return tmp; +} + +void linked_init(linked_list *l) { + l->length = 0; +} + +void linked_destroy(linked_list *l) { + while (l->length != 0) free(linked_pop_node(l, 0)); +} + +int linked_search_int(linked_list *l, int data) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data) return 1; + } + return 0; +} + +int linked_search_node(linked_list *l, int data, int place) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data && iter->place == place) return 1; + } + return 0; +} + +// insert data to bottom of list +int linked_push_int(linked_list *l, int data) { + if (linked_search_int(l, data)) return 0; + linked_node *tmp = linked_node_init(data); + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->bottom->next = tmp; + tmp->prev = l->bottom; + l->bottom = tmp; + } + return 1; +} + +// insert data to top of list +int linked_unshift_int(linked_list *l, int data) { + if (linked_search_int(l, data)) return 0; + linked_node *tmp = linked_node_init(data); + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->top->prev = tmp; + tmp->next = l->top; + l->top = tmp; + } + return 1; +} + +// look at data of index (negative value for looking from the bottom: -1:=l->bottom->data) +int linked_seek_int(linked_list *l, int index) { + if (index == 0) return l->top->data; + else if (index == -1) return l->bottom->data; + else if (index > 0) { + linked_node *iter = l->top->next; + for (int i=1; inext; + return iter->data; + } else if (index < 0) { + linked_node *iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + return iter->data; + } + return 0; +} + +// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) +int linked_pop_int(linked_list *l, int index) { + linked_node *iter = NULL; + if (index == 0) { + iter = l->top; + l->top = iter->next; + } else if (index == -1) { + iter = l->bottom; + l->bottom = iter->prev; + } else { + if (index > 0) { + iter = l->top->next; + for (int i=1; inext; + } else { + iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + } + iter->prev->next = iter->next; + iter->next->prev = iter->prev; + } + if (iter != NULL) { + l->length--; + int data = iter->data; + free(iter); + return data; + } else return 0; +} + +// insert data and place to bottom of list +int linked_push_node(linked_list *l, int data, int place) { + if (linked_search_node(l, data, place)) return 0; + linked_node *tmp = linked_node_init(data); + tmp->place = place; + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->bottom->next = tmp; + tmp->prev = l->bottom; + l->bottom = tmp; + } + return 1; +} + +// insert data and place to top of list +int linked_unshift_node(linked_list *l, int data, int place) { + if (linked_search_node(l, data, place)) return 0; + linked_node *tmp = linked_node_init(data); + tmp->place = place; + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->top->prev = tmp; + tmp->next = l->top; + l->top = tmp; + } + return 1; +} + +// return node of index (negative value for looking from the bottom: -1:=l->bottom) +linked_node *linked_seek_node(linked_list *l, int index) { + if (index == 0) return l->top; + else if (index == -1) return l->bottom; + else if (index > 0) { + linked_node *iter = l->top->next; + for (int i=1; inext; + return iter; + } else if (index < 0) { + linked_node *iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + return iter; + } + return NULL; +} + +// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) +linked_node *linked_pop_node(linked_list *l, int index) { + linked_node *iter = NULL; + if (index == 0) { + iter = l->top; + l->top = iter->next; + } else if (index == -1) { + iter = l->bottom; + l->bottom = iter->prev; + } else { + if (index > 0) { + iter = l->top->next; + for (int i=1; inext; + } else { + iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + } + iter->prev->next = iter->next; + iter->next->prev = iter->prev; + } + if (iter != NULL) { + l->length--; + return iter; + } else return NULL; +} + +void linked_print(linked_list *l) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter = iter->next) { + printf("(%d, %d) ", iter->data, iter->place); + } + printf("\n"); +} \ No newline at end of file diff --git a/linked_list.h b/linked_list.h new file mode 100644 index 0000000..7863acf --- /dev/null +++ b/linked_list.h @@ -0,0 +1,26 @@ +#pragma once + +typedef struct _linked_node { + int data, place; + struct _linked_node *next, *prev; +} linked_node; + +typedef struct { + linked_node *top, *bottom; + int length; +} linked_list; + +void linked_init(linked_list *l); +void linked_destroy(linked_list *l); + +int linked_push_int(linked_list *l, int data); +int linked_unshift_int(linked_list *l, int data); +int linked_seek_int(linked_list *l, int index); +int linked_pop_int(linked_list *l, int index); + +int linked_push_node(linked_list *l, int data, int place); +int linked_unshift_node(linked_list *l, int data, int place); +linked_node *linked_seek_node(linked_list *l, int index); +linked_node *linked_pop_node(linked_list *l, int index); + +void linked_print(linked_list *l); \ No newline at end of file From 9da074fd596cac18e1d2a6fa97ac36690d5990c7 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sat, 21 Dec 2019 02:01:49 +0900 Subject: [PATCH 21/37] ahocora finished? --- itoi/ahocora.h | 6 ------ itoi/grpwk.c | 10 ++++++---- itoi/{ahocora.c => itoi.c} | 29 +++++------------------------ itoi/itoi.h | 6 ++++++ 4 files changed, 17 insertions(+), 34 deletions(-) delete mode 100644 itoi/ahocora.h rename itoi/{ahocora.c => itoi.c} (80%) create mode 100644 itoi/itoi.h diff --git a/itoi/ahocora.h b/itoi/ahocora.h deleted file mode 100644 index 46d15f7..0000000 --- a/itoi/ahocora.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "../string_info.h" -#include "../linked_list.h" - -char *ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count); diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 77fdb17..275e329 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -2,12 +2,15 @@ #include #include -#include "grpwk.h" -#include "ahocora.h" #include "../linked_list.h" +#include "grpwk.h" +#include "itoi.h" // input_win.cから呼び出されるやつ char *grpwk(char *t, string_s s[], int len) { + char *ans = (char *)calloc(T_LENGTH + 1, sizeof(char)); + for (int i=0; i #include "../ahocorasick.h" -#include "ahocora.h" +#include "itoi.h" // outcome functions for testing void callback_add2linked_list(ahocorasick * aho, linked_list *l, int pos) { @@ -40,11 +40,13 @@ void convert(char *tmp, char *s, int len, unsigned long long bitchange) { } // アホコラを使用したあいまい検索の関数 -char *ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count) { +void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count) { /* おまじない */ ahocorasick aho; aho_init(&aho, s); aho_create_trie(&aho); + aho_register_option_lists(&aho, t_opt, s_count); + aho_register_match_callback(&aho, callback_add2linked_list); char tmp[120]; @@ -63,16 +65,7 @@ char *ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, i } aho_connect_trie(&aho); /* トライ木を整理 */ - - char *ans = (char *)calloc(T_LENGTH + 1, sizeof(char)); - for (int i=0; i Date: Sat, 21 Dec 2019 16:12:34 +0900 Subject: [PATCH 22/37] bug not fixed --- ahocorasick.c | 2 +- ahocorasick.h | 4 +-- ahotrie.c | 2 +- itoi/grpwk.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++-- itoi/itoi.c | 20 ++++++++++----- itoi/itoi.h | 4 ++- linked_list.c | 28 ++++++++++++++------ linked_list.h | 10 +++++--- 8 files changed, 116 insertions(+), 25 deletions(-) diff --git a/ahocorasick.c b/ahocorasick.c index 0240c63..e4cd6ee 100644 --- a/ahocorasick.c +++ b/ahocorasick.c @@ -68,7 +68,7 @@ inline void aho_register_match_callback(ahocorasick * aho, void (*callback_match aho->callback_match = callback_match; } -void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, int *s_count) { +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count) { aho->t_opt = t_opt; aho->s_count = s_count; } diff --git a/ahocorasick.h b/ahocorasick.h index 815c031..690d6b3 100644 --- a/ahocorasick.h +++ b/ahocorasick.h @@ -12,7 +12,7 @@ typedef struct _ahocorasick { void (*callback_match)(struct _ahocorasick * aho, linked_list* l, int pos); linked_list *t_opt; - int *s_count; + linked_list *s_count; } ahocorasick; void aho_init(ahocorasick * aho, string_s *s); @@ -28,4 +28,4 @@ void aho_clear_trie(ahocorasick * aho); int aho_search(ahocorasick * aho, char *text, int len); void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)); -void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, int *s_count); +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count); diff --git a/ahotrie.c b/ahotrie.c index 3b540fe..8d4a091 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -48,7 +48,7 @@ int trie_add(aho_trie * t, string_s * text, char * similar) { } current->end = TRUE; - linked_push_int(¤t->output_list, text->id); + linked_push_int(¤t->output_list, text->id, 1); return TRUE; } diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 275e329..5cb150a 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "../linked_list.h" #include "grpwk.h" @@ -14,11 +15,77 @@ char *grpwk(char *t, string_s s[], int len) { int from, to; for (from = 0; fromlen; t_index++) { + while (t_opt[t_index + s_pos].length != 0) { + // the other option + linked_node *other = linked_pop_node(&t_opt[t_index + s_pos], 0); + if (other->data == s_id || s_count[other->data].length == 0) { // same as the insert option + free(other); + continue; + } + + printf("(%d %d) ", other->data, other->place); + // go to s_count[other.id] and delete the option to insert here + if (linked_delete_int(&s_count[other->data], t_index + s_pos - other->place)) { + // reinsert the deleted option to s_opt + s_opt_insert(s_opt, s_count[other->data].length, other->data); + } + free(other); + } + } + printf("\n"); + sleep(1); + + /* insert text to ans */ + for (int i=0; ilen; i++) { + ans[s_pos + i] = text->str[i]; + } + } + + for (int i=0; i<100; i++) linked_destroy(&s_opt[i]); + for (int i=0; itop; for (int v=0; vlength; v++, iter = iter->next) { - // s_count[i]++ - aho->s_count[iter->data]++; + string_s *text = &aho->s[iter->data]; + + // s_count[i].append(text.pos) + linked_push_int(&aho->s_count[iter->data], pos-text->len+1, 1); // <- index of first letter - string_s text = aho->s[iter->data]; // t_opt[i].append(i, place) - for (int i=0; it_opt[pos-text.len+1 + i], iter->data, i); + for (int i=0; ilen; i++) { + linked_push_node(&aho->t_opt[pos-text->len+1 + i], iter->data, i, 1); } } } @@ -40,7 +41,7 @@ void convert(char *tmp, char *s, int len, unsigned long long bitchange) { } // アホコラを使用したあいまい検索の関数 -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count) { +void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count) { /* おまじない */ ahocorasick aho; aho_init(&aho, s); @@ -79,3 +80,10 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, in // } // } } + +int s_opt_insert(linked_list *s_opt, int s_count, int index) { + if (s_count < 100) { + linked_push_int(&s_opt[s_count], index, 0); + return 1; + } else return 0; +} diff --git a/itoi/itoi.h b/itoi/itoi.h index 9c28145..13be4d6 100644 --- a/itoi/itoi.h +++ b/itoi/itoi.h @@ -3,4 +3,6 @@ #include "../string_info.h" #include "../linked_list.h" -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, int *s_count); +void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); + +int s_opt_insert(linked_list *s_opt, int s_count, int index); diff --git a/linked_list.c b/linked_list.c index 8cfceef..97ce20d 100644 --- a/linked_list.c +++ b/linked_list.c @@ -7,6 +7,7 @@ linked_node *linked_node_init(int data) { linked_node *tmp = (linked_node *)malloc(sizeof(linked_node)); tmp->data = data; + tmp->place = 0; return tmp; } @@ -35,8 +36,8 @@ int linked_search_node(linked_list *l, int data, int place) { } // insert data to bottom of list -int linked_push_int(linked_list *l, int data) { - if (linked_search_int(l, data)) return 0; +int linked_push_int(linked_list *l, int data, int search) { + if (search && linked_search_int(l, data)) return 0; linked_node *tmp = linked_node_init(data); if (l->length++ == 0) { l->top = tmp; @@ -50,8 +51,8 @@ int linked_push_int(linked_list *l, int data) { } // insert data to top of list -int linked_unshift_int(linked_list *l, int data) { - if (linked_search_int(l, data)) return 0; +int linked_unshift_int(linked_list *l, int data, int search) { + if (search && linked_search_int(l, data)) return 0; linked_node *tmp = linked_node_init(data); if (l->length++ == 0) { l->top = tmp; @@ -109,8 +110,8 @@ int linked_pop_int(linked_list *l, int index) { } // insert data and place to bottom of list -int linked_push_node(linked_list *l, int data, int place) { - if (linked_search_node(l, data, place)) return 0; +int linked_push_node(linked_list *l, int data, int place, int search) { + if (search && linked_search_node(l, data, place)) return 0; linked_node *tmp = linked_node_init(data); tmp->place = place; if (l->length++ == 0) { @@ -125,8 +126,8 @@ int linked_push_node(linked_list *l, int data, int place) { } // insert data and place to top of list -int linked_unshift_node(linked_list *l, int data, int place) { - if (linked_search_node(l, data, place)) return 0; +int linked_unshift_node(linked_list *l, int data, int place, int search) { + if (search && linked_search_node(l, data, place)) return 0; linked_node *tmp = linked_node_init(data); tmp->place = place; if (l->length++ == 0) { @@ -188,4 +189,15 @@ void linked_print(linked_list *l) { printf("(%d, %d) ", iter->data, iter->place); } printf("\n"); +} + +int linked_delete_int(linked_list *l, int data) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data) { + linked_pop_int(l, v); + return 1; + } + } + return 0; } \ No newline at end of file diff --git a/linked_list.h b/linked_list.h index 7863acf..4627624 100644 --- a/linked_list.h +++ b/linked_list.h @@ -13,14 +13,16 @@ typedef struct { void linked_init(linked_list *l); void linked_destroy(linked_list *l); -int linked_push_int(linked_list *l, int data); -int linked_unshift_int(linked_list *l, int data); +int linked_push_int(linked_list *l, int data, int search); +int linked_unshift_int(linked_list *l, int data, int search); int linked_seek_int(linked_list *l, int index); int linked_pop_int(linked_list *l, int index); -int linked_push_node(linked_list *l, int data, int place); -int linked_unshift_node(linked_list *l, int data, int place); +int linked_push_node(linked_list *l, int data, int place, int search); +int linked_unshift_node(linked_list *l, int data, int place, int search); linked_node *linked_seek_node(linked_list *l, int index); linked_node *linked_pop_node(linked_list *l, int index); +int linked_delete_int(linked_list *l, int data); + void linked_print(linked_list *l); \ No newline at end of file From 7fba9bc16591fcad70bc6fe6d48440501870d64b Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sat, 21 Dec 2019 17:09:38 +0900 Subject: [PATCH 23/37] no bugs but slow --- itoi/grpwk.c | 8 ++------ linked_list.c | 6 ++++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 5cb150a..ced375d 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "../linked_list.h" #include "grpwk.h" @@ -40,12 +39,12 @@ char *grpwk(char *t, string_s s[], int len) { else for (int i=2; i<100; i++) { if (s_opt[i].length != 0) { s_id = linked_pop_int(&s_opt[i], 0); - printf("i = %d, ", i); break; } } if (s_id == -1) break; // no option found - printf("id: %d\n", s_id); + // if (s_count[s_id].length == 0) + // printf("id: %05d, options: %02d\n", s_id, s_count[s_id].length); if (s_count[s_id].length == 0) continue; // option already taken /* delete all other s that overlaps with the option */ @@ -65,7 +64,6 @@ char *grpwk(char *t, string_s s[], int len) { continue; } - printf("(%d %d) ", other->data, other->place); // go to s_count[other.id] and delete the option to insert here if (linked_delete_int(&s_count[other->data], t_index + s_pos - other->place)) { // reinsert the deleted option to s_opt @@ -74,8 +72,6 @@ char *grpwk(char *t, string_s s[], int len) { free(other); } } - printf("\n"); - sleep(1); /* insert text to ans */ for (int i=0; ilen; i++) { diff --git a/linked_list.c b/linked_list.c index 97ce20d..55b7487 100644 --- a/linked_list.c +++ b/linked_list.c @@ -8,6 +8,8 @@ linked_node *linked_node_init(int data) { linked_node *tmp = (linked_node *)malloc(sizeof(linked_node)); tmp->data = data; tmp->place = 0; + tmp->next = NULL; + tmp->prev = NULL; return tmp; } @@ -98,8 +100,8 @@ int linked_pop_int(linked_list *l, int index) { iter = l->bottom->prev; for (int i=-2; i>index; i--) iter = iter->prev; } - iter->prev->next = iter->next; - iter->next->prev = iter->prev; + if (iter->prev != NULL) iter->prev->next = iter->next; + if (iter->next != NULL) iter->next->prev = iter->prev; } if (iter != NULL) { l->length--; From 8511d4d8adbfdaade1b371d18da32e64147bd5b1 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sat, 21 Dec 2019 17:48:48 +0900 Subject: [PATCH 24/37] function names changed --- itoi/grpwk.c | 24 +----------------------- itoi/itoi.c | 24 ++++++++++++++++++++++++ itoi/itoi.h | 1 + 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/itoi/grpwk.c b/itoi/grpwk.c index ced375d..66dd079 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -43,35 +43,13 @@ char *grpwk(char *t, string_s s[], int len) { } } if (s_id == -1) break; // no option found - // if (s_count[s_id].length == 0) - // printf("id: %05d, options: %02d\n", s_id, s_count[s_id].length); if (s_count[s_id].length == 0) continue; // option already taken - - /* delete all other s that overlaps with the option */ // option's text and place: index of first letter within t string_s *text = &s[s_id]; int s_pos = linked_pop_int(&s_count[s_id], 0); // TODO: maybe better way to select the index above - linked_destroy(&s_count[s_id]); - - // discriminate other options within the substituted places - for (int t_index=0; t_indexlen; t_index++) { - while (t_opt[t_index + s_pos].length != 0) { - // the other option - linked_node *other = linked_pop_node(&t_opt[t_index + s_pos], 0); - if (other->data == s_id || s_count[other->data].length == 0) { // same as the insert option - free(other); - continue; - } - // go to s_count[other.id] and delete the option to insert here - if (linked_delete_int(&s_count[other->data], t_index + s_pos - other->place)) { - // reinsert the deleted option to s_opt - s_opt_insert(s_opt, s_count[other->data].length, other->data); - } - free(other); - } - } + discriminate(s_id, s_pos, text, t_opt, s_opt, s_count); /* insert text to ans */ for (int i=0; ilen; i++) { diff --git a/itoi/itoi.c b/itoi/itoi.c index b0a4518..4c84d7f 100644 --- a/itoi/itoi.c +++ b/itoi/itoi.c @@ -87,3 +87,27 @@ int s_opt_insert(linked_list *s_opt, int s_count, int index) { return 1; } else return 0; } + +/* delete all other s that overlaps with the option */ +void discriminate(int s_id, int s_pos, string_s *text, linked_list *t_opt, linked_list *s_opt, linked_list *s_count) { + linked_destroy(&s_count[s_id]); + + // discriminate other options within the substituted places + for (int t_index=0; t_indexlen; t_index++) { + while (t_opt[t_index + s_pos].length != 0) { + // the other option + linked_node *other = linked_pop_node(&t_opt[t_index + s_pos], 0); + if (other->data == s_id || s_count[other->data].length == 0) { // same as the insert option + free(other); + continue; + } + + // go to s_count[other.id] and delete the option to insert here + if (linked_delete_int(&s_count[other->data], t_index + s_pos - other->place)) { + // reinsert the deleted option to s_opt + s_opt_insert(s_opt, s_count[other->data].length, other->data); + } + free(other); + } + } +} \ No newline at end of file diff --git a/itoi/itoi.h b/itoi/itoi.h index 13be4d6..2c18f93 100644 --- a/itoi/itoi.h +++ b/itoi/itoi.h @@ -6,3 +6,4 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); int s_opt_insert(linked_list *s_opt, int s_count, int index); +void discriminate(int s_id, int s_pos, string_s *text, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); From f1e80c6d508c6c92a9df0198671079ec04d74a18 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sat, 21 Dec 2019 18:36:46 +0900 Subject: [PATCH 25/37] ready to connect with BM --- itoi/grpwk.c | 15 +++++++++++++-- itoi/itoi.c | 30 +++++++++++++----------------- itoi/itoi.h | 2 +- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/itoi/grpwk.c b/itoi/grpwk.c index 66dd079..f363026 100644 --- a/itoi/grpwk.c +++ b/itoi/grpwk.c @@ -32,6 +32,13 @@ char *grpwk(char *t, string_s s[], int len) { s_opt_insert(s_opt, s_count[i].length, i); } + /* delete options where t is already determined by BM */ + for (int i=0; ilen; i++) { + discriminate(s_pos+i, t_opt, s_opt, s_count); + } /* insert text to ans */ for (int i=0; ilen; i++) { diff --git a/itoi/itoi.c b/itoi/itoi.c index 4c84d7f..b7b4f6e 100644 --- a/itoi/itoi.c +++ b/itoi/itoi.c @@ -89,25 +89,21 @@ int s_opt_insert(linked_list *s_opt, int s_count, int index) { } /* delete all other s that overlaps with the option */ -void discriminate(int s_id, int s_pos, string_s *text, linked_list *t_opt, linked_list *s_opt, linked_list *s_count) { - linked_destroy(&s_count[s_id]); - +void discriminate(int t_index, linked_list *t_opt, linked_list *s_opt, linked_list *s_count) { // discriminate other options within the substituted places - for (int t_index=0; t_indexlen; t_index++) { - while (t_opt[t_index + s_pos].length != 0) { - // the other option - linked_node *other = linked_pop_node(&t_opt[t_index + s_pos], 0); - if (other->data == s_id || s_count[other->data].length == 0) { // same as the insert option - free(other); - continue; - } - - // go to s_count[other.id] and delete the option to insert here - if (linked_delete_int(&s_count[other->data], t_index + s_pos - other->place)) { - // reinsert the deleted option to s_opt - s_opt_insert(s_opt, s_count[other->data].length, other->data); - } + while (t_opt[t_index].length != 0) { + // the other option + linked_node *other = linked_pop_node(&t_opt[t_index], 0); + if (s_count[other->data].length == 0) { // same as the insert option free(other); + continue; + } + + // go to s_count[other.id] and delete the option to insert here + if (linked_delete_int(&s_count[other->data], t_index - other->place)) { + // reinsert the deleted option to s_opt + s_opt_insert(s_opt, s_count[other->data].length, other->data); } + free(other); } } \ No newline at end of file diff --git a/itoi/itoi.h b/itoi/itoi.h index 2c18f93..7c9962f 100644 --- a/itoi/itoi.h +++ b/itoi/itoi.h @@ -6,4 +6,4 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); int s_opt_insert(linked_list *s_opt, int s_count, int index); -void discriminate(int s_id, int s_pos, string_s *text, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); +void discriminate(int t_index, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); From eeebf16f8e9bb8d154faaec189d34bdc5ec2b49a Mon Sep 17 00:00:00 2001 From: udemegane Date: Sat, 21 Dec 2019 18:40:42 +0900 Subject: [PATCH 26/37] =?UTF-8?q?=E6=BA=96=E5=82=99=E5=AE=8C=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constructions.c | 110 +++++++++++++++++++++ constructions.h | 9 ++ example/BM+.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++ example/BM.h | 32 ++++++ example/grpwk.c | 29 ++++-- example/grpwk.h | 8 +- 6 files changed, 438 insertions(+), 8 deletions(-) create mode 100644 constructions.c create mode 100644 constructions.h create mode 100644 example/BM+.c create mode 100644 example/BM.h diff --git a/constructions.c b/constructions.c new file mode 100644 index 0000000..682e635 --- /dev/null +++ b/constructions.c @@ -0,0 +1,110 @@ +// +// Created by world on 2019/12/07. +// +#include +#include +#include +#include "string_info.h" + + +int comp(const void *p, const void *q) +{ + return ((string_s *)q)->len - ((string_s *)p)->len; +} + +void ConstructSMatrix(string_s * s_i,int matsize) +{ + printf("Accepted input text\n"); + qsort(s_i, matsize, sizeof(string_s), comp); + printf("s_i sort complete\n"); +} + +void ConstructTout(string_out *t_out, char *t_temp){ + strcpy(t_out->str, t_temp); + int i; + for(i=0; t_temp[i] != '\0'; i++){ + t_out->str[i] = 'x'; + } + //printf("Preparing output text structure\n"); +} + +void ConstructTin(string_out *t_in, char *t_temp){ + strcpy(t_in->str, t_temp); + int i,j,start=0,temp_id=-1; + if(t_temp[0] == 'x'){ + for(i=0;t_temp[i]=='x';i++) + start = i; + } + for(i=start; t_temp[i] != '\0'; i++){ + if(t_temp[i] == 'x'){ + temp_id = i-1; + for(j=1;t_temp[i - 1 + j]=='x'; j++){ + t_in->shift_var[i-1 + j] = j; + } + i+=j-1; + } + } + //printf("Preparing input text structure\n"); +} + +/* + + +link NEW(Item item, link f, link b) +{ + link x = malloc(sizeof *x); + x->item = item; + x->f = f; + x->b = b; + return x; +} + +void ConstructDLL(char s[120], int n) +{ + Item temp; + key(temp) = n; + strcpy(temp.Str, s); + + if (head == NULL) + { + head = NEW(temp, NULL, tail, 0); + tail = head; + } + else + { + tail->b = NEW(temp, tail, NULL, 0); + tail = tail->b; + } +} + +void Assign(string_s *S_temp, link link_temp, int n) +{ + if (link_temp == tail) + { + strcpy(S_temp[n].str, (link_temp->item).Str); + S_temp[n].len = strlen((link_temp->item).Str); + } + else + { + Assign(S_temp, link_temp->b, n + 1); + strcpy(S_temp[n].str, (link_temp->item).Str); + S_temp[n].len = strlen((link_temp->item).Str); + } +} + +int comp(const void *p, const void *q) +{ + //printf("compared\n"); + return ((string_s *)q)->len - ((string_s *)p)->len; +} + +void ConstructSMatrix(int n) +{ + string_s *S_temp; + S_temp = malloc(sizeof(string_s *) * n); + S = S_temp; + Assign(S, head, 0); + qsort(S, n, sizeof(string_s), comp); + printf("sort complete\n"); +} + */ \ No newline at end of file diff --git a/constructions.h b/constructions.h new file mode 100644 index 0000000..b1ccfcd --- /dev/null +++ b/constructions.h @@ -0,0 +1,9 @@ +// +// Created by world on 2019/12/07. +// +#include "string_info.h" +void ConstructSMatrix(string_s * s_i, int matsize); +void ConstructTout(string_out *t_out, char *t_in); +void ConstructTin(string_out *t_in, char *t_temp); + + diff --git a/example/BM+.c b/example/BM+.c new file mode 100644 index 0000000..3046b3e --- /dev/null +++ b/example/BM+.c @@ -0,0 +1,258 @@ +// +// Created by world on 2019/12/07. +// +#pragma GCC optimize("O3") + +#include "../constructions.h" +#include "../string_info.h" +#include "../linked_list.h" +#include "grpwk.h" +#include "BM.h" +#include +#include +#include +#include +#include +//#include +#include +#include + +//文字の比較に使用 単に見栄えを良くしてるだけ +#define ignore -1 +#define success 1 +#define failure 0 + +//これより短いs_iは処理しない + +typedef struct +{ + string_out *t_in; + string_s *s; + string_out *t_out; + int skipnum; +} Fthreadstructure; + +void BM_main(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt); + +void BM_entrance(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt) +{ + BM_main(t_in, s, s_size, s_id, t_out, s_count, t_opt); +} + +void BM_exit(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out) +{ + //printf("BM complete: %s\n",t_out->str); + //template_entrance(t, s, s_size, s_id, t_out); +} + +clock_t times_clock() +{ + struct tms t; + return times(&t); +} + +// for debug +int swapsum = 0, swapnum = 0; + +int BM(string_out *t_in, string_s *s, string_out *t_out, int s_id, linked_list *s_count, linked_list *t_opt) +{ + /*----------------------initialize-------------------------*/ + int t_id, esc, comp_var, point, lens_i; + string_s s_iBase, *s_i; + s_i = &(s_iBase); + /*---------------------------------------------------------*/ + for (int i = 0; 1; i++) + { + s_id++; + s_i = &s[i]; + + //t_id:s_iの最後尾がいる場所 + t_id = s_i->len - 1; + //esc:一致した文字の個数 + esc = 0; + //comp_var:何回比較したか + comp_var = 0; + //point:比較済みの文字の中で左から見てxに最も近い場所 + point = t_id; + lens_i = s_i->len; + int table[110][4]; + + /*---------------------makeShiftTable----------------------*/ + for (int k = 0; k < lens_i - 1; k++) + { + int Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][0] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][1] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][2] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][3] = Tcounter; + } + /*---------------------------------------------------------*/ + + while (t_id - 1 <= T_LENGTH) + { + int flag = 1; + //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ + if (t_out->str[t_id] != 'x') + { + t_id += t_out->shift_var[t_id - lens_i]; + point = t_id; + } + + //s_iが指定位置t_idにマッチするか確認 + int branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); + if (((t_in->str[t_id - comp_var] != 'x') && branch)) + { + //failware + flag = 0; + esc = 0; + } + else if (!branch) + { + //success + esc++; + comp_var++; + } + else + { + //ignore + comp_var += t_in->shift_var[t_id - comp_var]; + point = t_id - comp_var; + } + + while ((flag == 1) && (esc < 21) && (lens_i - 1 - comp_var >= 0) && (t_id - comp_var != 0)) + { + /*----------------------DebugPrint-------------------------*/ + /* + printf("t_s:"); + int j; + for(j=0;jstr);j++) + printf("%d",t_out->shift_var[j]); + printf("\nt :%s\n",t_in->str); + printf("out:%s\n",t_out->str); + printf("s_i:"); + + for(j=0;jlen+1;j++) + printf(" "); + printf("%s\n",s_i->str); + printf("cmp:"); + for(j=0;jstr[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); + if (((t_in->str[t_id - comp_var] != 'x') && branch)) + { + //failware + flag = 0; + esc = 0; + } + else if (!branch) + { + //success + esc++; + comp_var++; + } + else + { + //ignore + comp_var += t_in->shift_var[t_id - comp_var]; + } + } + //マッチした場合t_outに挿入,そうでないなら次の場所を探索 + if (flag == 1) + { + if (lens_i > 23) + { + int x, y, f = 0; + for (x = lens_i - 1, y = 0; x >= 0; x--, y++) + { + t_out->str[t_id - y] = s_i->str[x]; + t_out->shift_var[t_id - y] = lens_i - x - 1; + } + t_out->shift_var[t_id - y] = lens_i; + esc = 0; + goto next; + } + else + { + //printf("%d %d\n",s_id,t_id); + linked_push_int(&s_count[s_id], t_id, 0); + //printf("pushed\n"); + for (int j = 0; j < lens_i - 1; j++) + { + linked_push_node(&t_opt[t_id + j], s_id, j, 0); + } + //printf("completed\n"); + } + } + /* + if ((t_in->str[point] - 'a' < 4) && (t_in->str[point] - 'a' >= 0) ) { + temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, + table[comp_var][t_in->str[t_id - comp_var] - 'a']); + swiftsum += temp; + swiftnum ++; + } else { + elsecount++; + temp = shift(t_in->str[t_id - comp_var], s_i, comp_var); + } + */ + //int temp = High(table[t_id - point + 1][(t_id == point)&&t_in->str[t_id+1]!='x'? t_in->str[point+1] - 'a':t_in->str[point] - 'a'] + 1, + // table[comp_var][t_in->str[t_id - comp_v ar] - 'a']); + int temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, + table[comp_var][t_in->str[t_id - comp_var] - 'a']); + + t_id += temp; + comp_var = 0; + point = t_id; + } + + ///////Jump to here/////// + next: + + if (lens_i <= Min_len) + { + break; + } + } + return s_id; +} + +void BM_main(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt) +{ + int temp; + + temp = BM(t_in, s, t_out, s_id, s_count, t_opt); + printf("%d\n", temp); + + BM_exit(t_in, s, s_size, s_id, t_out); +} diff --git a/example/BM.h b/example/BM.h new file mode 100644 index 0000000..9f5edb7 --- /dev/null +++ b/example/BM.h @@ -0,0 +1,32 @@ +#define index_N 16 + +typedef struct Node *link; +struct Node{ + int *id; + link b; + int *x; + int *count; +}; +#define Min_len 14 +#define ThreadNum 1 + +#define High(A, B) (A > B) ? A : B +#define rep(i, n) for (int i = 0; i < (int)(n); i++) + +#define idvar(A,B) (A - 'a')*4 + (B - 'a') +#define aa 0 +#define ab 1 +#define ac 2 +#define ad 3 +#define ba 4 +#define bb 5 +#define bc 6 +#define bd 7 +#define ca 8 +#define cb 9 +#define cc 10 +#define cd 11 +#define da 12 +#define db 13 +#define dc 14 +#define dd 15 \ No newline at end of file diff --git a/example/grpwk.c b/example/grpwk.c index e4335ae..b30bd72 100644 --- a/example/grpwk.c +++ b/example/grpwk.c @@ -1,11 +1,28 @@ #include #include - +#include +#include "../constructions.h" #include "grpwk.h" -char *grpwk(const string_s t, const string_s s[], int len) { - char *str = (char *)malloc(sizeof(char) * 100); - sprintf(str, "I got %d data!", len); +char *grpwk(char *t, string_s *s, int len) +{ + + string_out t_out_base, *t_out, t_in_base, *t_in; + t_out = &t_out_base; + t_in = &t_in_base; + ConstructSMatrix(s, len); + ConstructTout(t_out, t); + ConstructTin(t_in, t); + + linked_list *t_opt = (linked_list *)malloc(sizeof(linked_list) * T_LENGTH); + for (int i = 0; i < T_LENGTH; i++) + linked_init(&t_opt[i]); + int s_count_tmp[len]; + memset(s_count_tmp, 0, sizeof(int) * len); + linked_list s_count[len]; + memset(s_count, 0, sizeof(linked_list) * len); + + BM_entrance(t_in, s, len, 0, t_out, s_count, t_opt); - return str; -} \ No newline at end of file + return t_out->str; +} diff --git a/example/grpwk.h b/example/grpwk.h index 4a430d7..abe3a5e 100644 --- a/example/grpwk.h +++ b/example/grpwk.h @@ -1,5 +1,9 @@ #pragma once -#include "../string_s.h" +#include "../string_info.h" +#include "../linked_list.h" -char *grpwk(const string_s t, const string_s s[], int len); \ No newline at end of file +char *grpwk(char* t, string_s * s, int len); +void writeTout(char* t_temp); +void template_entrance(string_out * t_in, string_s * s, int s_len, int now_id, string_out *t_out); +void BM_entrance(string_out * t_in, string_s * s, int s_len, int now_id, string_out *t_out, linked_list *s_count, linked_list *t_opt); From 20eb382ccab8f5d5be31160900aae7a303016525 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 00:45:33 +0900 Subject: [PATCH 27/37] bm test --- constructions.c | 6 +++--- itoi/itoi.c | 11 ----------- middlesub/BM+.c | 38 +++++++++++++++++++------------------- middlesub/BM.h | 4 ++-- middlesub/grpwk.c | 41 ++++++++++++++++++++++++++++++++++------- middlesub/grpwk.h | 2 +- middlesub/itoi.c | 11 ----------- 7 files changed, 59 insertions(+), 54 deletions(-) diff --git a/constructions.c b/constructions.c index 6d28e20..fe08ab4 100644 --- a/constructions.c +++ b/constructions.c @@ -49,9 +49,9 @@ void ConstructTin(string_out *t_in, char *t_temp){ /* -link NEW(Item item, link f, link b) +Link NEW(Item item, Link f, Link b) { - link x = malloc(sizeof *x); + Link x = malloc(sizeof *x); x->item = item; x->f = f; x->b = b; @@ -76,7 +76,7 @@ void ConstructDLL(char s[120], int n) } } -void Assign(string_s *S_temp, link link_temp, int n) +void Assign(string_s *S_temp, Link link_temp, int n) { if (link_temp == tail) { diff --git a/itoi/itoi.c b/itoi/itoi.c index b7b4f6e..525912e 100644 --- a/itoi/itoi.c +++ b/itoi/itoi.c @@ -68,17 +68,6 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, li aho_connect_trie(&aho); /* トライ木を整理 */ aho_search(&aho, t, T_LENGTH); aho_destroy(&aho); - - /* TODO: test */ - // for (int i=from; i 100) printf("%d: %d, %s(%d)\n", s[i].id, s_count[s[i].id], s[i].str, s[i].len); - // } - // for (int i=0; ilen - 1; + t_id = lens_i - 1; //esc:一致した文字の個数 esc = 0; //comp_var:何回比較したか @@ -44,34 +44,34 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s int table[110][4]; /*---------------------makeShiftTable----------------------*/ - for (int k = 0; k < s_i->len - 1; k++) + for (int k = 0; k < lens_i - 1; k++) { int Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) + if ((s_i->str[lens_i - 1 - k - j] == (0 + 'a')) || (lens_i - 1 - k - j < 0)) break; } table[k][0] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) + if ((s_i->str[lens_i - 1 - k - j] == (1 + 'a')) || (lens_i - 1 - k - j < 0)) break; } table[k][1] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) + if ((s_i->str[lens_i - 1 - k - j] == (2 + 'a')) || (lens_i - 1 - k - j < 0)) break; } table[k][2] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) + if ((s_i->str[lens_i - 1 - k - j] == (3 + 'a')) || (lens_i - 1 - k - j < 0)) break; } table[k][3] = Tcounter; @@ -84,12 +84,12 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ if (t_out->str[t_id] != 'x') { - t_id += t_out->shift_var[t_id - s_i->len]; + t_id += t_out->shift_var[t_id - lens_i]; point = t_id; } //s_iが指定位置t_idにマッチするか確認 - int branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); + int branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); if (((t_in->str[t_id - comp_var] != 'x') && branch)) { //failware @@ -109,7 +109,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s point = t_id - comp_var; } - while ((flag == 1) && (esc < 21) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) + while ((flag == 1) && (esc < 21) && (lens_i - 1 - comp_var >= 0) && (t_id - comp_var != 0)) { /*----------------------DebugPrint-------------------------*/ /* @@ -121,7 +121,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s printf("out:%s\n",t_out->str); printf("s_i:"); - for(j=0;jlen+1;j++) + for(j=0;jstr); printf("cmp:"); @@ -135,7 +135,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s printf("t_id:%d comp_var:%d\n",t_id,comp_var); /*---------------------------------------------------------*/ /*---------------------------------------------------------*/ - branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); + branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); if (((t_in->str[t_id - comp_var] != 'x') && branch)) { //failware @@ -157,26 +157,26 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //マッチした場合t_outに挿入,そうでないなら次の場所を探索 if (flag == 1) { - if (s_i->len > 23) + if (lens_i > 24) { int x, y, f = 0; - for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) + for (x = lens_i - 1, y = 0; x >= 0; x--, y++) { t_out->str[t_id - y] = s_i->str[x]; - t_out->shift_var[t_id - y] = s_i->len - x - 1; + t_out->shift_var[t_id - y] = lens_i - x - 1; } - t_out->shift_var[t_id - y] = s_i->len; + t_out->shift_var[t_id - y] = lens_i; esc = 0; continue; } else { //printf("%d %d\n",s[i].id,t_id); - linked_push_int(&s_count[s[i].id], t_id, 0); + linked_push_int(&s_count[s_i->id], t_id-lens_i+1, 0); //printf("pushed\n"); - for (int j = 0; j < s_i->len - 1; j++) + for (int j = 0; j < lens_i; j++) { - linked_push_node(&t_opt[t_id + j], s[i].id, j, 0); + linked_push_node(&t_opt[t_id-lens_i+1 + j], s_i->id, j, 0); } //printf("completed\n"); } diff --git a/middlesub/BM.h b/middlesub/BM.h index b1d7586..3e7a00f 100644 --- a/middlesub/BM.h +++ b/middlesub/BM.h @@ -3,10 +3,10 @@ #include "../string_info.h" #include "../linked_list.h" -typedef struct Node *link; +typedef struct Node *Link; struct Node{ int *id; - link b; + Link b; int *x; int *count; }; diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index 4860cd4..71ad32f 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -6,6 +6,7 @@ #include "grpwk.h" #include "itoi.h" #include "BM.h" +#include // input_win.cから呼び出されるやつ char *grpwk(char *t, string_s *s, int len) { @@ -18,11 +19,13 @@ char *grpwk(char *t, string_s *s, int len) { string_out *t_in = (string_out *)malloc(sizeof(string_out)); string_out *t_out = (string_out *)malloc(sizeof(string_out)); - memset(t_out->str, 'x', T_LENGTH); + for (int i=0; istr[i] = 'x'; + } t_out->str[T_LENGTH] = '\0'; ConstructTin(t_in, t); - for (int i=0; istr[i] != 'x') { + if (t[i] != t_out->str[i]) { + printf("error: %d\n", i); + // usleep(10000); + } + t[i] = t_out->str[i]; + } + } + printf("%d\n", strlen(t_out->str)); + return t; ahocoralike(t, s, bm_until, aho_until, t_opt, s_count); - printf("ahocora end\n"); + printf("ahocora done\n"); linked_list s_opt[100]; memset(s_opt, 0, sizeof(linked_list) * 100); // s_opt init - for (int i=bm_until; ilen; i++) { + if (t_out->str[s_pos + i] != 'x') printf("eorro\n"); t_out->str[s_pos + i] = text->str[i]; } } diff --git a/middlesub/grpwk.h b/middlesub/grpwk.h index d3ef973..c92281b 100644 --- a/middlesub/grpwk.h +++ b/middlesub/grpwk.h @@ -4,6 +4,6 @@ #include "../linked_list.h" #define BM_TO 17 -#define AHO_TO 5 +#define AHO_TO 15 char *grpwk(char *t, string_s *s, int len); diff --git a/middlesub/itoi.c b/middlesub/itoi.c index b7b4f6e..525912e 100644 --- a/middlesub/itoi.c +++ b/middlesub/itoi.c @@ -68,17 +68,6 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, li aho_connect_trie(&aho); /* トライ木を整理 */ aho_search(&aho, t, T_LENGTH); aho_destroy(&aho); - - /* TODO: test */ - // for (int i=from; i 100) printf("%d: %d, %s(%d)\n", s[i].id, s_count[s[i].id], s[i].str, s[i].len); - // } - // for (int i=0; i Date: Sun, 22 Dec 2019 14:42:49 +0900 Subject: [PATCH 28/37] =?UTF-8?q?=E3=83=90=E3=82=B0=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/dat0_out | 0 middlesub/BM+.c | 14 +++++++------- middlesub/grpwk.h | 4 ++-- test | Bin 0 -> 27616 bytes 4 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 data/dat0_out create mode 100644 test diff --git a/data/dat0_out b/data/dat0_out new file mode 100644 index 0000000..e69de29 diff --git a/middlesub/BM+.c b/middlesub/BM+.c index 1840a45..d67c53b 100644 --- a/middlesub/BM+.c +++ b/middlesub/BM+.c @@ -10,11 +10,6 @@ #include "../constructions.h" #include "BM.h" -//文字の比較に使用 単に見栄えを良くしてるだけ -#define ignore -1 -#define success 1 -#define failure 0 - //これより短いs[i]は処理しない typedef struct @@ -30,7 +25,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s /*----------------------initialize-------------------------*/ int t_id, esc, comp_var, point; /*---------------------------------------------------------*/ - for (int i = 0; istr[t_id] != 'x') { - t_id += t_out->shift_var[t_id - s_i->len]; + t_id += High(t_out->shift_var[t_id - lens_i], t_out->shift_var[t_id]); point = t_id; } @@ -111,6 +106,11 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s while ((flag == 1) && (esc < 21) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) { + if (t_out->str[t_id] != 'x') + { + t_id += High(t_out->shift_var[t_id - lens_i], t_out->shift_var[t_id]); + point = t_id; + } /*----------------------DebugPrint-------------------------*/ /* printf("t_s:"); diff --git a/middlesub/grpwk.h b/middlesub/grpwk.h index d3ef973..a10ea24 100644 --- a/middlesub/grpwk.h +++ b/middlesub/grpwk.h @@ -3,7 +3,7 @@ #include "../string_info.h" #include "../linked_list.h" -#define BM_TO 17 -#define AHO_TO 5 +#define BM_TO 35 +#define AHO_TO 15 char *grpwk(char *t, string_s *s, int len); diff --git a/test b/test new file mode 100644 index 0000000000000000000000000000000000000000..c7905b19d8ff6abc669d5aa77b689e4f183f6e26 GIT binary patch literal 27616 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 EUyn-f(EtDd literal 0 HcmV?d00001 From fd6aa65f65cb2a99859e99f538800c5fe0021c87 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 15:50:34 +0900 Subject: [PATCH 29/37] some bug fixed --- input_win.c | 2 +- middlesub/BM+.c | 42 +++++++++++++++++++++--------------------- middlesub/grpwk.c | 3 ++- test | Bin 27616 -> 0 bytes 4 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 test diff --git a/input_win.c b/input_win.c index ebd1afc..878d5dc 100644 --- a/input_win.c +++ b/input_win.c @@ -42,7 +42,7 @@ int main_prg(int argc, char **argv) FILE *fp_out = fopen(argv[2], "w"); assert(fp_out != NULL); - char t[T_LENGTH]; + char t[T_LENGTH + 1]; string_s s[50000]; // input t diff --git a/middlesub/BM+.c b/middlesub/BM+.c index 8a37e3b..0d5dbc5 100644 --- a/middlesub/BM+.c +++ b/middlesub/BM+.c @@ -23,13 +23,13 @@ typedef struct void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s_count, linked_list *t_opt) { /*----------------------initialize-------------------------*/ - int t_id, esc, comp_var, point, lens_i; + int t_id, esc, comp_var, point; /*---------------------------------------------------------*/ for (int i = 0; i < to; i++) { string_s *s_i = &s[i]; //t_id:s_iの最後尾がいる場所 - t_id = lens_i - 1; + t_id = s_i->len - 1; //esc:一致した文字の個数 esc = 0; //comp_var:何回比較したか @@ -39,34 +39,34 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s int table[110][4]; /*---------------------makeShiftTable----------------------*/ - for (int k = 0; k < lens_i - 1; k++) + for (int k = 0; k < s_i->len - 1; k++) { int Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[lens_i - 1 - k - j] == (0 + 'a')) || (lens_i - 1 - k - j < 0)) + if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) break; } table[k][0] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[lens_i - 1 - k - j] == (1 + 'a')) || (lens_i - 1 - k - j < 0)) + if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) break; } table[k][1] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[lens_i - 1 - k - j] == (2 + 'a')) || (lens_i - 1 - k - j < 0)) + if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) break; } table[k][2] = Tcounter; rep(j, 120) { Tcounter = j; - if ((s_i->str[lens_i - 1 - k - j] == (3 + 'a')) || (lens_i - 1 - k - j < 0)) + if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) break; } table[k][3] = Tcounter; @@ -79,12 +79,12 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ if (t_out->str[t_id] != 'x') { - t_id += High(t_out->shift_var[t_id - lens_i], t_out->shift_var[t_id]); + t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); point = t_id; } //s_iが指定位置t_idにマッチするか確認 - int branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); + int branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); if (((t_in->str[t_id - comp_var] != 'x') && branch)) { //failware @@ -104,11 +104,11 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s point = t_id - comp_var; } - while ((flag == 1) && (esc < 21) && (lens_i - 1 - comp_var >= 0) && (t_id - comp_var != 0)) + while ((flag == 1) && (esc < 21) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) { if (t_out->str[t_id] != 'x') { - t_id += High(t_out->shift_var[t_id - lens_i], t_out->shift_var[t_id]); + t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); point = t_id; } /*----------------------DebugPrint-------------------------*/ @@ -121,7 +121,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s printf("out:%s\n",t_out->str); printf("s_i:"); - for(j=0;jlen+1;j++) printf(" "); printf("%s\n",s_i->str); printf("cmp:"); @@ -135,7 +135,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s printf("t_id:%d comp_var:%d\n",t_id,comp_var); /*---------------------------------------------------------*/ /*---------------------------------------------------------*/ - branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); + branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); if (((t_in->str[t_id - comp_var] != 'x') && branch)) { //failware @@ -157,26 +157,26 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //マッチした場合t_outに挿入,そうでないなら次の場所を探索 if (flag == 1) { - if (lens_i > 24) + if (s_i->len > 24) { - int x, y, f = 0; - for (x = lens_i - 1, y = 0; x >= 0; x--, y++) + int x, y; + for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) { t_out->str[t_id - y] = s_i->str[x]; - t_out->shift_var[t_id - y] = lens_i - x - 1; + t_out->shift_var[t_id - y] = s_i->len - x - 1; } - t_out->shift_var[t_id - y] = lens_i; + t_out->shift_var[t_id - y] = s_i->len; esc = 0; continue; } else { //printf("%d %d\n",s[i].id,t_id); - linked_push_int(&s_count[s_i->id], t_id - lens_i + 1, 0); + linked_push_int(&s_count[s_i->id], t_id - s_i->len + 1, 0); //printf("pushed\n"); - for (int j = 0; j < lens_i; j++) + for (int j = 0; j < s_i->len; j++) { - linked_push_node(&t_opt[t_id - lens_i + 1 + j], s_i->id, j, 0); + linked_push_node(&t_opt[t_id - s_i->len + 1 + j], s_i->id, j, 0); } //printf("completed\n"); } diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index 71ad32f..cf271f2 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -23,6 +23,7 @@ char *grpwk(char *t, string_s *s, int len) { t_out->str[i] = 'x'; } t_out->str[T_LENGTH] = '\0'; + // ConstructTout(t_out, t); ConstructTin(t_in, t); // for (int i=0; istr[i] != 'x') { - if (t[i] != t_out->str[i]) { + if (t[i] != t_out->str[i] && t[i] != 'x') { printf("error: %d\n", i); // usleep(10000); } diff --git a/test b/test deleted file mode 100644 index c7905b19d8ff6abc669d5aa77b689e4f183f6e26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27616 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 EUyn-f(EtDd From 6c98129db7936274a98bb12e29313cbdce0544a0 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 18:54:31 +0900 Subject: [PATCH 30/37] aho added --- middlesub/grpwk.c | 11 +++++------ middlesub/grpwk.h | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index cf271f2..b573ac1 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -26,7 +26,6 @@ char *grpwk(char *t, string_s *s, int len) { // ConstructTout(t_out, t); ConstructTin(t_in, t); - // for (int i=0; istr[i] != 'x') { if (t[i] != t_out->str[i] && t[i] != 'x') { - printf("error: %d\n", i); + // printf("error: %d\n", i); // usleep(10000); - } - t[i] = t_out->str[i]; + } else t[i] = t_out->str[i]; } } - printf("%d\n", strlen(t_out->str)); - return t; + // printf("%d\n", strlen(t_out->str)); + // return t; + for (int i=0; i Date: Sun, 22 Dec 2019 19:06:14 +0900 Subject: [PATCH 31/37] =?UTF-8?q?=E3=83=90=E3=82=B0=E6=B2=BB=E3=81=A3?= =?UTF-8?q?=E3=81=9F=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BC_readme.txt | 252 ++++++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 6 ++ a.out | Bin 0 -> 8600 bytes input_win.c | 8 +- main.c | 6 ++ middlesub/BM+.c | 53 +++------- middlesub/grpwk.c | 109 +++++++++++++------- middlesub/grpwk.h | 4 +- out.txt | 0 test | Bin 0 -> 23520 bytes 10 files changed, 360 insertions(+), 78 deletions(-) create mode 100644 BC_readme.txt create mode 100644 CMakeLists.txt create mode 100644 a.out create mode 100644 main.c create mode 100644 out.txt create mode 100644 test diff --git a/BC_readme.txt b/BC_readme.txt new file mode 100644 index 0000000..1d66921 --- /dev/null +++ b/BC_readme.txt @@ -0,0 +1,252 @@ +要点まとめ + +変更点: +s_iのconst修飾子を除外(ソートの必要性があるため) +t_outの型をchar型からstring_out型に変更(既に一致済のs_iに関する情報を持っておきたかった) + +BM.cの動作はボイヤームーアとほぼ同じだが虫食いのため微妙に違う動作をする。 +そのためソースコードがネット上に転がってるものとだいぶ違うことに注意。 +例えば +t:abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_0:abcddbcdbcbaaaabcccaabaaada +s_1:bdaabaadaacbdbcaad +s_2:.... +のとき、以下のような動作をする。 +ここで、t_idはt_inにおけるs_iの最後尾,comp_varはs_iのどこを比較しているかをあらわしている。 +15文字以上一致したらそこで比較を打ち切り成功探索とみなしている。 + + +udemegane@DESKTOP-K5R8CJ6:~/work/grpwk/example$ ./a.out +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:0 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:1 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:2 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:3 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:4 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:5 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:6 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:7 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:8 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:9 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:10 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:11 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:12 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:13 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:14 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:15 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i:abcddbcdbcbaaaabcccaabaaada +cmp: ^ +t_id:26 comp_var:16 + +Detected the exact position of s_i!! +Before s_i assignment:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +After s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + +Whether or not already matched|character:c +Caution|Already matched:Character is not 'x',shifts s_i position +out:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:44 comp_var:0 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:44 comp_var:1 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:44 comp_var:2 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:44 comp_var:3 + +Shift s_i by 1 + +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:45 comp_var:0 + +Shift s_i by 1 + +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:46 comp_var:0 + +Shift s_i by 1 + +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:47 comp_var:0 + +Shift s_i by 3 + +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:50 comp_var:0 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:50 comp_var:1 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:50 comp_var:2 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:50 comp_var:3 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:50 comp_var:4 + +Shift s_i by 4 + +Whether or not already matched|character:x +Did not match +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:0 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:1 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:2 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:3 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:4 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:5 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:6 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:7 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:8 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:9 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:10 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:11 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:12 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:13 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:14 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:15 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:16 +t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada +s_i: bdaabaadaacbdbcaad +cmp: ^ +t_id:54 comp_var:17 + +Detected the exact position of s_i!! +Before s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +After s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxbdaabaadaacbdbcaadxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + +BM complete: abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxbdaabaadaacbdbcaadxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +It continues... \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..507c6c6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.15) +project(grpwk C) + +set(CMAKE_C_STANDARD 99) + +add_executable(grpwk ./middlesub linked_list.c linked_list.h string_info.h input_win.c example/BM.h example/grpwk.h example/Algorithm_template.c constructions.c constructions.h example/BM.c example/BM+.c example/test.c example/Speedtest.c example/BM_temp.c example/BM_temp2.c example/adeumeru.c) \ No newline at end of file diff --git a/a.out b/a.out new file mode 100644 index 0000000000000000000000000000000000000000..ad143683288175214236edd7a1d3cc568fdca742 GIT binary patch literal 8600 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 MSK37;D(STUC#M^MxBvhE literal 0 HcmV?d00001 diff --git a/input_win.c b/input_win.c index 878d5dc..ce775a2 100644 --- a/input_win.c +++ b/input_win.c @@ -36,14 +36,18 @@ int sort_f(const void *a, const void *b) { int main_prg(int argc, char **argv) { + assert(argc == 3); FILE *fp_in = fopen(argv[1], "r"); assert(fp_in != NULL); FILE *fp_out = fopen(argv[2], "w"); assert(fp_out != NULL); - char t[T_LENGTH + 1]; + + + char t[T_LENGTH]; string_s s[50000]; + //s = malloc(sizeof(string_s) * 50000); // input t fscanf(fp_in, "%s", t); @@ -56,6 +60,8 @@ int main_prg(int argc, char **argv) for (int i=0; i + +int main() { + printf("Hello, World!\n"); + return 0; +} diff --git a/middlesub/BM+.c b/middlesub/BM+.c index 0d5dbc5..4be1d47 100644 --- a/middlesub/BM+.c +++ b/middlesub/BM+.c @@ -4,30 +4,20 @@ #pragma GCC optimize("O3") #include -#include #include - #include "../constructions.h" #include "BM.h" -//これより短いs[i]は処理しない - -typedef struct -{ - string_out *t_in; - string_s *s; - string_out *t_out; - int skipnum; -} Fthreadstructure; - void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s_count, linked_list *t_opt) { /*----------------------initialize-------------------------*/ - int t_id, esc, comp_var, point; + int t_id, esc, comp_var, point, t_len = strlen(t_in->str); + string_s *s_i; + /*---------------------------------------------------------*/ for (int i = 0; i < to; i++) { - string_s *s_i = &s[i]; + s_i = &s[i]; //t_id:s_iの最後尾がいる場所 t_id = s_i->len - 1; //esc:一致した文字の個数 @@ -39,7 +29,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s int table[110][4]; /*---------------------makeShiftTable----------------------*/ - for (int k = 0; k < s_i->len - 1; k++) + for (int k = 0; k < s_i->len- 1; k++) { int Tcounter; rep(j, 120) @@ -73,7 +63,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s } /*---------------------------------------------------------*/ - while (t_id - 1 <= T_LENGTH) + while (t_id - 1 <= t_len) { int flag = 1; //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ @@ -104,7 +94,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s point = t_id - comp_var; } - while ((flag == 1) && (esc < 21) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) + while ((flag == 1) && (esc < 23) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) { if (t_out->str[t_id] != 'x') { @@ -112,7 +102,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s point = t_id; } /*----------------------DebugPrint-------------------------*/ - /* +/* printf("t_s:"); int j; for(j=0;jstr);j++) @@ -157,7 +147,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //マッチした場合t_outに挿入,そうでないなら次の場所を探索 if (flag == 1) { - if (s_i->len > 24) + if (s_i->len > 3) { int x, y; for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) @@ -167,33 +157,17 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s } t_out->shift_var[t_id - y] = s_i->len; esc = 0; - continue; + goto next; } else { - //printf("%d %d\n",s[i].id,t_id); linked_push_int(&s_count[s_i->id], t_id - s_i->len + 1, 0); - //printf("pushed\n"); for (int j = 0; j < s_i->len; j++) { - linked_push_node(&t_opt[t_id - s_i->len + 1 + j], s_i->id, j, 0); + linked_push_node(&t_opt[t_id - s_i->len+ 1 + j], s_i->id, j, 0); } - //printf("completed\n"); } } - /* - if ((t_in->str[point] - 'a' < 4) && (t_in->str[point] - 'a' >= 0) ) { - temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, - table[comp_var][t_in->str[t_id - comp_var] - 'a']); - swiftsum += temp; - swiftnum ++; - } else { - elsecount++; - temp = shift(t_in->str[t_id - comp_var], s_i, comp_var); - } - */ - //int temp = High(table[t_id - point + 1][(t_id == point)&&t_in->str[t_id+1]!='x'? t_in->str[point+1] - 'a':t_in->str[point] - 'a'] + 1, - // table[comp_var][t_in->str[t_id - comp_v ar] - 'a']); int temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, table[comp_var][t_in->str[t_id - comp_var] - 'a']); @@ -201,5 +175,10 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s comp_var = 0; point = t_id; } + next: + if(0){ + printf(""); + } + } } diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index b573ac1..952acda 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -9,57 +9,76 @@ #include // input_win.cから呼び出されるやつ -char *grpwk(char *t, string_s *s, int len) { +char *grpwk(char *t, string_s *s, int len) +{ + printf("test\n"); /* 文字数の区切りを決定 */ int bm_until, aho_until; - for (bm_until = 0; bm_untilstr[i] = 'x'; } - t_out->str[T_LENGTH] = '\0'; - // ConstructTout(t_out, t); + t_out->str[strlen(t)] = '\0'; ConstructTin(t_in, t); - // init option lists linked_list *t_opt = (linked_list *)malloc(sizeof(linked_list) * T_LENGTH); - for (int i=0; istr[i] != 'x') { - if (t[i] != t_out->str[i] && t[i] != 'x') { - // printf("error: %d\n", i); + int err; + for (int i = 0; i < T_LENGTH; i++) + err += (t_in->str[i] != t_out->str[i] && t_in->str[i] != 'x' && t_out->str[i] != 'x' ); + printf("err:%d\n",err); + /* + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x') + { + if (t[i] != t_out->str[i]) + { + printf("error: %d\n", i); // usleep(10000); - } else t[i] = t_out->str[i]; + } + t[i] = t_out->str[i]; } } - // printf("%d\n", strlen(t_out->str)); - // return t; - for (int i=0; istr)); + + return t; ahocoralike(t, s, bm_until, aho_until, t_opt, s_count); printf("ahocora done\n"); linked_list s_opt[100]; memset(s_opt, 0, sizeof(linked_list) * 100); // s_opt init - for (int i=0; istr[i] != 'x') { + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x') + { discriminate(i, t_opt, s_opt, s_count); } } @@ -77,18 +96,25 @@ char *grpwk(char *t, string_s *s, int len) { // } // linked_print(&s_opt[1]); - while (1) { + while (1) + { // get next s to insert into ans int s_id = -1; - if (s_opt[1].length != 0) s_id = linked_pop_int(&s_opt[1], 0); - else for (int i=2; i<100; i++) { - if (s_opt[i].length != 0) { - s_id = linked_pop_int(&s_opt[i], 0); - break; + if (s_opt[1].length != 0) + s_id = linked_pop_int(&s_opt[1], 0); + else + for (int i = 2; i < 100; i++) + { + if (s_opt[i].length != 0) + { + s_id = linked_pop_int(&s_opt[i], 0); + break; + } } - } - if (s_id == -1) break; // no option found - if (s_count[s_id].length == 0) continue; // option already taken + if (s_id == -1) + break; // no option found + if (s_count[s_id].length == 0) + continue; // option already taken // printf("id: %05d (%02d), opt: %d: %s\n", s_id, s[s_id].len, s_count[s_id].length, s[s_id].str); // option's text and place: index of first letter within t @@ -98,23 +124,30 @@ char *grpwk(char *t, string_s *s, int len) { /* delete other options */ string_s *text = &s[s_id]; - for (int i=0; ilen; i++) { - discriminate(s_pos+i, t_opt, s_opt, s_count); + for (int i = 0; i < text->len; i++) + { + discriminate(s_pos + i, t_opt, s_opt, s_count); } /* insert text to ans */ - for (int i=0; ilen; i++) { - if (t_out->str[s_pos + i] != 'x') printf("eorro\n"); + for (int i = 0; i < text->len; i++) + { + if (t_out->str[s_pos + i] != 'x') + printf("eorro\n"); t_out->str[s_pos + i] = text->str[i]; } } - for (int i=0; i<100; i++) linked_destroy(&s_opt[i]); - for (int i=0; istr[i] != 'x') t[i] = t_out->str[i]; + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x') + t[i] = t_out->str[i]; } free(t_in); free(t_out); diff --git a/middlesub/grpwk.h b/middlesub/grpwk.h index d3ef973..554ff13 100644 --- a/middlesub/grpwk.h +++ b/middlesub/grpwk.h @@ -3,7 +3,7 @@ #include "../string_info.h" #include "../linked_list.h" -#define BM_TO 17 -#define AHO_TO 5 +#define BM_TO 19 +#define AHO_TO 15 char *grpwk(char *t, string_s *s, int len); diff --git a/out.txt b/out.txt new file mode 100644 index 0000000..e69de29 diff --git a/test b/test new file mode 100644 index 0000000000000000000000000000000000000000..d57848778bb0c3295c3406368b7c233eae997327 GIT binary patch literal 23520 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 literal 0 HcmV?d00001 From 1aa41566c8b4200b7ab6a19bfcd0b21fddcfd5bf Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 22:41:49 +0900 Subject: [PATCH 32/37] final ver --- a.out | Bin 8600 -> 0 bytes ahotrie.c | 5 +++-- compile.sh | 2 +- linked_list.c | 4 ++++ middlesub/BM+.c | 8 ++----- middlesub/grpwk.c | 50 ++++++++++++++++++++---------------------- middlesub/grpwk.h | 4 ++-- middlesub/itoi.c | 2 +- test | Bin 23520 -> 0 bytes main.c => test_main.c | 0 10 files changed, 37 insertions(+), 38 deletions(-) delete mode 100644 a.out delete mode 100644 test rename main.c => test_main.c (100%) diff --git a/a.out b/a.out deleted file mode 100644 index ad143683288175214236edd7a1d3cc568fdca742..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8600 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 MSK37;D(STUC#M^MxBvhE diff --git a/ahotrie.c b/ahotrie.c index 8d4a091..aef65f1 100644 --- a/ahotrie.c +++ b/ahotrie.c @@ -39,7 +39,7 @@ int trie_add(aho_trie * t, string_s * text, char * similar) { for (int i=0; ilen; i++) { int char_id = similar[i] - 'a'; - if (char_id > 3 || char_id < 0) return FALSE; + if (char_id > MAX_NODE - 1 || char_id < 0) return FALSE; if (current->child[char_id] == NULL) current->child[char_id] = node_init(char_id, current); else current->child[char_id]->ref_count++; @@ -119,8 +119,9 @@ void trie_delete(aho_trie * t) { int find_node(aho_node ** node, int text) { if (*node == NULL) return FALSE; + if (text > MAX_NODE - 1 || text < 0) return FALSE; - if ((*node)->child[text] != NULL && text <= 3 && text >= 0) { + if ((*node)->child[text] != NULL) { *node = (*node)->child[text]; return TRUE; } diff --git a/compile.sh b/compile.sh index d92223b..46604d7 100644 --- a/compile.sh +++ b/compile.sh @@ -19,7 +19,7 @@ usage_exit() { while getopts :hfd:t:f OPT do case $OPT in - f) CFLAGS="-fast" # コンパイルをワーニングなしで実行 + f) CFLAGS="-Ofast" # コンパイルをワーニングなしで実行 echo "You are running the compiler withOUT -Wall option!" ;; d) DIR=$OPTARG;; # grpwk.cのあるディレクトリの設定(トップディレクトリとこのディレクトリしかコンパイルされないためファイル構成には注意) diff --git a/linked_list.c b/linked_list.c index 55b7487..b5e1fec 100644 --- a/linked_list.c +++ b/linked_list.c @@ -105,6 +105,10 @@ int linked_pop_int(linked_list *l, int index) { } if (iter != NULL) { l->length--; + if (l->length == 0) { + l->top = NULL; + l->bottom = NULL; + } int data = iter->data; free(iter); return data; diff --git a/middlesub/BM+.c b/middlesub/BM+.c index 4be1d47..84431dc 100644 --- a/middlesub/BM+.c +++ b/middlesub/BM+.c @@ -147,7 +147,7 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s //マッチした場合t_outに挿入,そうでないなら次の場所を探索 if (flag == 1) { - if (s_i->len > 3) + if (s_i->len > 22) { int x, y; for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) @@ -175,10 +175,6 @@ void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s comp_var = 0; point = t_id; } - next: - if(0){ - printf(""); - } - + next:; } } diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index 952acda..2cbbce8 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -11,26 +11,24 @@ // input_win.cから呼び出されるやつ char *grpwk(char *t, string_s *s, int len) { - printf("test\n"); /* 文字数の区切りを決定 */ int bm_until, aho_until; for (bm_until = 0; bm_until < len; ++bm_until) - if (s[bm_until].len == BM_TO) + if (s[bm_until].len <= BM_TO) break; for (aho_until = bm_until; aho_until < len; aho_until++) - if (s[aho_until].len == AHO_TO) + if (s[aho_until].len <= AHO_TO) break; /* BMはじめ */ string_out *t_in = (string_out *)malloc(sizeof(string_out)); string_out *t_out = (string_out *)malloc(sizeof(string_out)); - printf("%d\n",bm_until); - for (int i = 0; i < strlen(t); i++) + for (int i = 0; i < T_LENGTH; i++) { t_out->str[i] = 'x'; } - t_out->str[strlen(t)] = '\0'; + t_out->str[T_LENGTH] = '\0'; ConstructTin(t_in, t); // init option lists @@ -42,27 +40,24 @@ char *grpwk(char *t, string_s *s, int len) BM(t_in, s, bm_until, t_out, s_count, t_opt); printf("bm done\n"); - int err; - for (int i = 0; i < T_LENGTH; i++) - err += (t_in->str[i] != t_out->str[i] && t_in->str[i] != 'x' && t_out->str[i] != 'x' ); - printf("err:%d\n",err); - /* + // int err = 0; + // for (int i = 0; i < T_LENGTH; i++) + // err += (t_in->str[i] != t_out->str[i] && t_in->str[i] != 'x' && t_out->str[i] != 'x' ); + // printf("err:%d\n",err); for (int i = 0; i < T_LENGTH; i++) { if (t_out->str[i] != 'x') { - if (t[i] != t_out->str[i]) - { - printf("error: %d\n", i); - // usleep(10000); - } + // if (t[i] != t_out->str[i]) + // { + // printf("error: %d\n", i); + // usleep(10000); + // } t[i] = t_out->str[i]; - } + } else if (t[i] == 'x') t[i] = 'a'; } - */ - printf("%d\n", strlen(t_out->str)); + // return t; - return t; ahocoralike(t, s, bm_until, aho_until, t_opt, s_count); printf("ahocora done\n"); @@ -82,7 +77,7 @@ char *grpwk(char *t, string_s *s, int len) discriminate(i, t_opt, s_opt, s_count); } } - printf("dicrim done\n"); + printf("discrim done\n"); /* TODO: test */ // for (int i=0; ilen; i++) { - if (t_out->str[s_pos + i] != 'x') - printf("eorro\n"); + // if (t_out->str[s_pos + i] != 'x') printf("eorro\n"); t_out->str[s_pos + i] = text->str[i]; } } @@ -146,9 +141,12 @@ char *grpwk(char *t, string_s *s, int len) for (int i = 0; i < T_LENGTH; i++) { - if (t_out->str[i] != 'x') - t[i] = t_out->str[i]; + if (t_out->str[i] != 'x') { + if (t_copy[i] != 'x') t[i] = t_copy[i]; + else t[i] = t_out->str[i]; + } } + free(t_in); free(t_out); return t; diff --git a/middlesub/grpwk.h b/middlesub/grpwk.h index 554ff13..d8f02f2 100644 --- a/middlesub/grpwk.h +++ b/middlesub/grpwk.h @@ -3,7 +3,7 @@ #include "../string_info.h" #include "../linked_list.h" -#define BM_TO 19 -#define AHO_TO 15 +#define BM_TO 16 +#define AHO_TO 11 char *grpwk(char *t, string_s *s, int len); diff --git a/middlesub/itoi.c b/middlesub/itoi.c index 525912e..79e4da8 100644 --- a/middlesub/itoi.c +++ b/middlesub/itoi.c @@ -55,7 +55,7 @@ void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, li aho_add_match_text(&aho, &s[i]); /* 木にキーを追加 */ /* s[i]が虫食いされて生じうる文字列を木に追加 */ - int max_bit = s[i].len / 2; /* 虫食いされる個数は文字列長の半分以下に限定 */ + double max_bit = s[i].len / 2; /* 虫食いされる個数は文字列長の半分以下に限定 */ unsigned long long until = ((unsigned long long)1<m$i0F7rSe1b?Mr=$frmGl%TcSptc63HI=9nf@^9~V@2luo^$Vg=9yu} zx}U!9=kxxt7iP}A=bU@)x#ymH?vH2kY<8C{PIEXkmD06uXjE#wNMKx&u)ADl09;z3 zb`id>(#C7UQO;nTpt}SBRiq&)TER?-PY0xWg=qqj2**o41(k*bhe=v8u=i$xRZ!EM zjG%g?tG|R#DL5zuxLmfE$}an){tC+GwQ05fRkLSKtF4+^>#q;C zOl>KgJ$3fX{N{%I8QgD@PrSD-tKgPsyp?H5=W+NDj_5!7Zr6g_-dcan)WZ|n-M`K( z+dS>65mZ-wkp0T(pTIdb33q-9{9)joN%${L!M`E}J~st^Z3_JC6!@hn@K>e4H>SYP zPl3N91%6u!d_xNS+rT^VNlZ0BB(p!^lHvagcqcxIX(JHVBqFH{zw?rt&DNR&P2R?J zT6IICuU=~m2AVaGr#VpRUE}fAtnpM=`fCa6t*LC%ytNJ9H6T|uH~X3bf`;m~s95K# zYxV^|^EWqm=g#$1H+w7VtF^kyTGY|18=L&~fokpB%?(Y&oy5mgZSfUh1jxHThQin*+Y4^3p}M4fVeA z%2l-_a&=upy%gyYtVtPZHqm@a!z`j4{mZa&f+D_!5gp*8`K0FkIKO{1MW{UzcR82S zwP$2Gc!eJ;K$`X+qPi6?ReWn5DF|gU9xA*`;xk=NW>9!l?zu(aDOS<^SE<*A&r(Rh zhz+lFC-R^Te~FEM$cCpFqtbm6KLQA{gGx0vJlRX7MjKwmSfaJq@b-16)rPmn;jK12 zwXM<)8(!InXuE89xdd~S-8Q^5G2@@I;VEXRwAY3orI3L8Y&@9tEjsxmzOyH|kfU-95&L_i zNRwZsG7V9GHBhT(ufgOasR)ygUK#DJ&d;9E#`0GlCM(Cv5cxG?49^|JBkIxbUN0Go(@>&{QzYLsnbe|{rNCNqCdpGvcDP}l!Ny;jg4n?BiI{Rcs?4{4fmjK zR`i-~;C^RxMZSfqktu>Qq?_&`{Ra2oM|$@49Uo=qjNS~JeUyD~CptME*?r_ik?X;| zkD7exFgIargvo*s>mD@AT1bZJYRNlfbgvZjEoV9ot=5bKB@1?;{hzx4s&q4B@)U@G zK10(xLQG2!Ou#Umo1|&`zfPp^te+r{rhf_$Ir0UxH`}SU9_ql9Ach|h1A6g35smiy zn0SDI79?T+M#A!hFpm({NW#{}3Cj_}s-&>Tg|HeSjDQffiiF)DgpC!#ZX#jV6MuMT zUqO;)mBPt7F@=7bpSNM8L=tnnXT%VrUcUkQn!p=j`7DbzbC>%%_tF_imTsY_^j zENgj>(sHudPWhM;;T>m4X~r69A%+f7oX3i7__gd&I85E6X2>SSf0FcJ*wE<)DanQn z&$`I2gs0cP?dhuDE5xPu*fr?N2AiuLT7UHn6C}7-Y=3tN&L^jr<41d6@$7_ zcHfSKN<;$NKY~4x#J-DKT)PytS>L7%>F<^xr`5Vq5wY4bOCz#|>w+3WU)l6>gxJKU zC20zxX$n$zTrC$==)q*`HY#38m_uFeUbcnl27^1&3%H#z8G`b;#Z80B4VGx@yddKHa2QT?%=>iFOY-c7)u04v3rQ zer3atOm}bMP^JCF8YNvbOvb7m7Fx_qi_jS&G*KlYj}AkzE{^e&`

] [-t ]" + echo "Usage: $0 [-f (-Ofast: no warning)] [-d ] [-t ]" } # コマンドラインオプションを設定 diff --git a/example/BM+.c b/example/BM+.c deleted file mode 100644 index fe68416..0000000 --- a/example/BM+.c +++ /dev/null @@ -1,256 +0,0 @@ -// -// Created by world on 2019/12/07. -// -#pragma GCC optimize("O3") - -#include -#include -#include -#include -#include -//#include -#include -#include - -#include "../constructions.h" -#include "BM.h" - -//文字の比較に使用 単に見栄えを良くしてるだけ -#define ignore -1 -#define success 1 -#define failure 0 - -//これより短いs_iは処理しない - -typedef struct -{ - string_out *t_in; - string_s *s; - string_out *t_out; - int skipnum; -} Fthreadstructure; - -void BM_main(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt); - -void BM_entrance(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt) -{ - BM_main(t_in, s, s_size, s_id, t_out, s_count, t_opt); -} - -void BM_exit(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out) -{ - //printf("BM complete: %s\n",t_out->str); - //template_entrance(t, s, s_size, s_id, t_out); -} - -clock_t times_clock() -{ - struct tms t; - return times(&t); -} - -// for debug -int swapsum = 0, swapnum = 0; - -int BM(string_out *t_in, string_s *s, string_out *t_out, int s_id, linked_list *s_count, linked_list *t_opt) -{ - /*----------------------initialize-------------------------*/ - int t_id, esc, comp_var, point, lens_i; - string_s s_iBase, *s_i; - s_i = &(s_iBase); - /*---------------------------------------------------------*/ - for (int i = 0; 1; i++) - { - s_id++; - s_i = &s[i]; - - //t_id:s_iの最後尾がいる場所 - t_id = s_i->len - 1; - //esc:一致した文字の個数 - esc = 0; - //comp_var:何回比較したか - comp_var = 0; - //point:比較済みの文字の中で左から見てxに最も近い場所 - point = t_id; - lens_i = s_i->len; - int table[110][4]; - - /*---------------------makeShiftTable----------------------*/ - for (int k = 0; k < lens_i - 1; k++) - { - int Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][0] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][1] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][2] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][3] = Tcounter; - } - /*---------------------------------------------------------*/ - - while (t_id - 1 <= T_LENGTH) - { - int flag = 1; - //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ - if (t_out->str[t_id] != 'x') - { - t_id += t_out->shift_var[t_id - lens_i]; - point = t_id; - } - - //s_iが指定位置t_idにマッチするか確認 - int branch = (t_in->str[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); - if (((t_in->str[t_id - comp_var] != 'x') && branch)) - { - //failware - flag = 0; - esc = 0; - } - else if (!branch) - { - //success - esc++; - comp_var++; - } - else - { - //ignore - comp_var += t_in->shift_var[t_id - comp_var]; - point = t_id - comp_var; - } - - while ((flag == 1) && (esc < 21) && (lens_i - 1 - comp_var >= 0) && (t_id - comp_var != 0)) - { - /*----------------------DebugPrint-------------------------*/ - /* - printf("t_s:"); - int j; - for(j=0;jstr);j++) - printf("%d",t_out->shift_var[j]); - printf("\nt :%s\n",t_in->str); - printf("out:%s\n",t_out->str); - printf("s_i:"); - - for(j=0;jlen+1;j++) - printf(" "); - printf("%s\n",s_i->str); - printf("cmp:"); - for(j=0;jstr[t_id - comp_var] != s_i->str[lens_i - 1 - comp_var]); - if (((t_in->str[t_id - comp_var] != 'x') && branch)) - { - //failware - flag = 0; - esc = 0; - } - else if (!branch) - { - //success - esc++; - comp_var++; - } - else - { - //ignore - comp_var += t_in->shift_var[t_id - comp_var]; - } - } - //マッチした場合t_outに挿入,そうでないなら次の場所を探索 - if (flag == 1) - { - if (lens_i > 23) - { - int x, y, f = 0; - for (x = lens_i - 1, y = 0; x >= 0; x--, y++) - { - t_out->str[t_id - y] = s_i->str[x]; - t_out->shift_var[t_id - y] = lens_i - x - 1; - } - t_out->shift_var[t_id - y] = lens_i; - esc = 0; - goto next; - } - else - { - //printf("%d %d\n",s_id,t_id); - linked_push_int(&s_count[s_id], t_id, 0); - //printf("pushed\n"); - for (int j = 0; j < lens_i - 1; j++) - { - linked_push_node(&t_opt[t_id + j], s_id, j, 0); - } - //printf("completed\n"); - } - } - /* - if ((t_in->str[point] - 'a' < 4) && (t_in->str[point] - 'a' >= 0) ) { - temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, - table[comp_var][t_in->str[t_id - comp_var] - 'a']); - swiftsum += temp; - swiftnum ++; - } else { - elsecount++; - temp = shift(t_in->str[t_id - comp_var], s_i, comp_var); - } - */ - //int temp = High(table[t_id - point + 1][(t_id == point)&&t_in->str[t_id+1]!='x'? t_in->str[point+1] - 'a':t_in->str[point] - 'a'] + 1, - // table[comp_var][t_in->str[t_id - comp_v ar] - 'a']); - int temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, - table[comp_var][t_in->str[t_id - comp_var] - 'a']); - - t_id += temp; - comp_var = 0; - point = t_id; - } - - ///////Jump to here/////// - next: - - if (lens_i <= Min_len) - { - break; - } - } - return s_id; -} - -void BM_main(string_out *t_in, string_s *s, int s_size, int s_id, string_out *t_out, linked_list *s_count, linked_list *t_opt) -{ - int temp; - - temp = BM(t_in, s, t_out, s_id, s_count, t_opt); - printf("%d\n", temp); - - BM_exit(t_in, s, s_size, s_id, t_out); -} diff --git a/example/BM.h b/example/BM.h deleted file mode 100644 index 134824c..0000000 --- a/example/BM.h +++ /dev/null @@ -1,36 +0,0 @@ -#define index_N 16 - -typedef struct Node *link; -struct Node{ - int *id; - link b; - int *x; - int *count; -}; -#define Min_len 14 -#define ThreadNum 1 - -#define High(A, B) (A > B) ? A : B -#define rep(i, n) for (int i = 0; i < (int)(n); i++) - -#define idvar(A,B) (A - 'a')*4 + (B - 'a') -#define aa 0 -#define ab 1 -#define ac 2 -#define ad 3 -#define ba 4 -#define bb 5 -#define bc 6 -#define bd 7 -#define ca 8 -#define cb 9 -#define cc 10 -#define cd 11 -#define da 12 -#define db 13 -#define dc 14 -#define dd 15 - -void writeTout(char* t_temp); -void template_entrance(string_out * t_in, string_s * s, int s_len, int now_id, string_out *t_out); -void BM_entrance(string_out * t_in, string_s * s, int s_len, int now_id, string_out *t_out, linked_list *s_count, linked_list *t_opt); diff --git a/example/grpwk.c b/example/grpwk.c deleted file mode 100644 index 12c84ec..0000000 --- a/example/grpwk.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -#include "../constructions.h" -#include "grpwk.h" -#include "BM.h" - -char *grpwk(char *t, string_s *s, int len) -{ - - string_out t_out_base, *t_out, t_in_base, *t_in; - t_out = &t_out_base; - t_in = &t_in_base; - ConstructSMatrix(s, len); - ConstructTout(t_out, t); - ConstructTin(t_in, t); - - linked_list *t_opt = (linked_list *)malloc(sizeof(linked_list) * T_LENGTH); - for (int i = 0; i < T_LENGTH; i++) - linked_init(&t_opt[i]); - int s_count_tmp[len]; - memset(s_count_tmp, 0, sizeof(int) * len); - linked_list s_count[len]; - memset(s_count, 0, sizeof(linked_list) * len); - - BM_entrance(t_in, s, len, 0, t_out, s_count, t_opt); - - return t_out->str; -} diff --git a/example/grpwk.h b/example/grpwk.h deleted file mode 100644 index b2844d1..0000000 --- a/example/grpwk.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "../string_info.h" - -char *grpwk(char* t, string_s * s, int len); \ No newline at end of file diff --git a/input_win.c b/input_win.c index ce775a2..5353df6 100644 --- a/input_win.c +++ b/input_win.c @@ -8,7 +8,7 @@ #include "string_info.h" // TODO: change here to include your files!! -#include "itoi/grpwk.h" +#include "middlesub/grpwk.h" int main_prg(int, char **); diff --git a/itoi/grpwk.c b/itoi/grpwk.c deleted file mode 100644 index 0437f49..0000000 --- a/itoi/grpwk.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include - -#include "grpwk.h" -#include "itoi.h" - -// input_win.cから呼び出されるやつ -char *grpwk(char *t, string_s *s, int len) { - char *ans = (char *)calloc(T_LENGTH + 1, sizeof(char)); - for (int i=0; ilen; i++) { - discriminate(s_pos+i, t_opt, s_opt, s_count); - } - - /* insert text to ans */ - for (int i=0; ilen; i++) { - ans[s_pos + i] = text->str[i]; - } - } - - for (int i=0; i<100; i++) linked_destroy(&s_opt[i]); - for (int i=0; i -#include -#include - -#include "../ahocorasick.h" -#include "itoi.h" - -// outcome functions for testing -void callback_add2linked_list(ahocorasick * aho, linked_list *l, int pos) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter = iter->next) { - string_s *text = &aho->s[iter->data]; - - // s_count[i].append(text.pos) - linked_push_int(&aho->s_count[iter->data], pos-text->len+1, 1); // <- index of first letter - - // t_opt[i].append(i, place) - for (int i=0; ilen; i++) { - linked_push_node(&aho->t_opt[pos-text->len+1 + i], iter->data, i, 1); - } - } -} - -// 入力されたintの中で何個のビットが立っているかを返す -int bitcount(unsigned long long bits) { - bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); - bits = (bits & 0x3333333333333333) + (bits >> 2 & 0x3333333333333333); - bits = (bits & 0x0f0f0f0f0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f0f0f0f0f); - bits = (bits & 0x00ff00ff00ff00ff) + (bits >> 8 & 0x00ff00ff00ff00ff); - bits = (bits & 0x0000ffff0000ffff) + (bits >> 16 & 0x0000ffff0000ffff); - return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); -} - -// bitchangeにおいて立っているビットの場所の文字を'a'に置換する -void convert(char *tmp, char *s, int len, unsigned long long bitchange) { - for (int i=0; i> i & 1) tmp[i] = 'a'; - else tmp[i] = s[i]; - } - tmp[len] = '\0'; -} - -// アホコラを使用したあいまい検索の関数 -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count) { - /* おまじない */ - ahocorasick aho; - aho_init(&aho, s); - aho_create_trie(&aho); - aho_register_option_lists(&aho, t_opt, s_count); - aho_register_match_callback(&aho, callback_add2linked_list); - - char tmp[120]; - - for (int i=from; idata].length == 0) { // same as the insert option - free(other); - continue; - } - - // go to s_count[other.id] and delete the option to insert here - if (linked_delete_int(&s_count[other->data], t_index - other->place)) { - // reinsert the deleted option to s_opt - s_opt_insert(s_opt, s_count[other->data].length, other->data); - } - free(other); - } -} \ No newline at end of file diff --git a/itoi/itoi.h b/itoi/itoi.h deleted file mode 100644 index 7c9962f..0000000 --- a/itoi/itoi.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "../string_info.h" -#include "../linked_list.h" - -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); - -int s_opt_insert(linked_list *s_opt, int s_count, int index); -void discriminate(int t_index, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); diff --git a/out.txt b/out.txt deleted file mode 100644 index e69de29..0000000 diff --git a/test_main.c b/test_main.c deleted file mode 100644 index f26b97c..0000000 --- a/test_main.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - printf("Hello, World!\n"); - return 0; -} diff --git a/queue_test.c b/test_queue.c similarity index 100% rename from queue_test.c rename to test_queue.c diff --git "a/\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" "b/\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" deleted file mode 100644 index be537eb44ca1e347e7a761c14b4f312c3e8c9543..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27 fcma!!%Fjy;DN4*MPD?F{<>dl#JyUFrdAS$>i985_ diff --git "a/\346\217\220\345\207\272\347\224\250/ahocorasick.c" "b/\346\217\220\345\207\272\347\224\250/ahocorasick.c" deleted file mode 100644 index e4cd6ee..0000000 --- "a/\346\217\220\345\207\272\347\224\250/ahocorasick.c" +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include - -#include "ahocorasick.h" - -// ahocorasick型の変数の初期化 -void aho_init(ahocorasick * aho, string_s *s) { - memset(aho, 0, sizeof(ahocorasick)); - aho->s = s; -} - -void aho_destroy(ahocorasick * aho) { - aho_clear_trie(aho); -} - -/** キー(string_s *s_i)を木に追加 - * return 挿入成功:TRUE、容量を超過:FALSE - */ -int aho_add_match_text(ahocorasick * aho, string_s *text) { - trie_add(&aho->trie, text, text->str); - return TRUE; -} - -/** 曖昧検索用文字列挿入用(木に挿入する文字列と探索成功時の返す文字列が違う場合に使用) - * 木に挿入する文字列をメモリに保存せずに済む - * data:曖昧の文字列、original:虫食い前のデータ - */ -int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original) { - trie_add(&aho->trie, original, data); - return TRUE; -} - -// トライ木を生成 -void aho_create_trie(ahocorasick * aho) { - trie_init(&aho->trie); -} - -// トライ木からアホコラを作る -void aho_connect_trie(ahocorasick * aho) { - trie_connect(&aho->trie); -} - -void aho_clear_trie(ahocorasick * aho) { - trie_destroy(&aho->trie); -} - -/** 検索関数(data:t'、len:len(t')) - * return マッチしたキーの数 - */ -int aho_search(ahocorasick * aho, char *data, int len) { - int counter = 0; - aho_node *current = &aho->trie.root; - - for (int i=0; idata); - aho->callback_match(aho, result, i); - } - - return counter; -} - -// 探索が成功した際に実行される関数を設定する関数 -inline void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)) { - aho->callback_match = callback_match; -} - -void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count) { - aho->t_opt = t_opt; - aho->s_count = s_count; -} diff --git "a/\346\217\220\345\207\272\347\224\250/ahocorasick.h" "b/\346\217\220\345\207\272\347\224\250/ahocorasick.h" deleted file mode 100644 index 690d6b3..0000000 --- "a/\346\217\220\345\207\272\347\224\250/ahocorasick.h" +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "ahotrie.h" -#include "string_info.h" -#include "linked_list.h" - -#define AHO_SIZE 45000 - -typedef struct _ahocorasick { - aho_trie trie; - string_s *s; - - void (*callback_match)(struct _ahocorasick * aho, linked_list* l, int pos); - linked_list *t_opt; - linked_list *s_count; -} ahocorasick; - -void aho_init(ahocorasick * aho, string_s *s); -void aho_destroy(ahocorasick * aho); - -int aho_add_match_text(ahocorasick * aho, string_s *text); -int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original); - -void aho_create_trie(ahocorasick * aho); -void aho_connect_trie(ahocorasick * aho); -void aho_clear_trie(ahocorasick * aho); - -int aho_search(ahocorasick * aho, char *text, int len); - -void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)); -void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count); diff --git "a/\346\217\220\345\207\272\347\224\250/ahotrie.c" "b/\346\217\220\345\207\272\347\224\250/ahotrie.c" deleted file mode 100644 index aef65f1..0000000 --- "a/\346\217\220\345\207\272\347\224\250/ahotrie.c" +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include - -#include "ahotrie.h" -#include "queue.h" - -// 新しいノードを生成 -aho_node *node_init(int data, aho_node * parent) { - aho_node *node = (aho_node *)malloc(sizeof(aho_node)); - memset(node, 0, sizeof(aho_node)); - node->data = data; - node->parent = parent; - node->ref_count = 1; - node->end = FALSE; - linked_init(&node->output_list); - return node; -} - -// トライ木を初期化 -void trie_init(aho_trie * t) { - if (t == NULL) t = (aho_trie *)malloc(sizeof(aho_trie)); - memset(t, 0, sizeof(aho_trie)); - t->root = *node_init(-1, NULL); -} - -// トライ木消去 -void trie_destroy(aho_trie * t) { - trie_delete(t); -} - -/** トライ木に文字列を挿入 - * string_s *text: ゴール - * char *similar: 入力文字列 - * - aho_add_match_textのときは text->str == similar - **/ -int trie_add(aho_trie * t, string_s * text, char * similar) { - aho_node *current = &t->root; - - for (int i=0; ilen; i++) { - int char_id = similar[i] - 'a'; - if (char_id > MAX_NODE - 1 || char_id < 0) return FALSE; - - if (current->child[char_id] == NULL) current->child[char_id] = node_init(char_id, current); - else current->child[char_id]->ref_count++; - - current = current->child[char_id]; - } - - current->end = TRUE; - linked_push_int(¤t->output_list, text->id, 1); - - return TRUE; -} - -int connect_link(aho_node *p, aho_node *q) { - if (p->failure_link == NULL || p->parent == NULL) { - q->failure_link = p; - return TRUE; - } - - aho_node *tmp = p->failure_link; - for (int i=0; ichild[i] == NULL) continue; - - if (tmp->child[i]->data == q->data) { - q->failure_link = tmp->child[i]; - - if (tmp->child[i]->end) q->output_link = tmp->child[i]; - else q->output_link = tmp->child[i]->output_link; - - return TRUE; - } - } - return FALSE; -} - -// トライ木をアホコラに合わせて再構成 -void trie_connect(aho_trie * t) { - queue que; - que_init(&que); - que_push(&que, &t->root); - - while (TRUE) { - aho_node *node = que_pop(&que); - if (node == NULL) break; - - for (int i=0; ichild[i] == NULL) continue; - - que_push(&que, node->child[i]); - - aho_node *tmp = node, *child = node->child[i]; - while (connect_link(tmp, child) == FALSE) tmp = tmp->failure_link; - } - } - - que_destroy(&que); -} - -void trie_delete(aho_trie * t) { - queue que; - que_init(&que); - que_push(&que, &t->root); - - while (TRUE) { - QUE_TYPE node = que_pop(&que); - if (node == NULL) break; - - for (int i=0; ichild[i] != NULL) que_push(&que, node->child[i]); - linked_destroy(&node->output_list); - - if (node->parent == NULL) continue; - free(node); - } - - que_destroy(&que); -} - -int find_node(aho_node ** node, int text) { - if (*node == NULL) return FALSE; - if (text > MAX_NODE - 1 || text < 0) return FALSE; - - if ((*node)->child[text] != NULL) { - *node = (*node)->child[text]; - return TRUE; - } - - return FALSE; -} - -// textが木に含まれる場合、終端に設定したlinked_listを返す。含まれない場合はNULL。 -linked_list *trie_find(aho_node ** node, char text) { - while (find_node(node, text - 'a') == FALSE) { - if (node == NULL || (*node)->parent == NULL) return NULL; - *node = (*node)->failure_link; - } - - if ((*node)->end) return &(*node)->output_list; - else if ((*node)->output_link) return &(*node)->output_link->output_list; - else return NULL; -} - -// トライ木を表示。ノードが多くなってくると使い物にならない。 -void trie_print(aho_trie * t) { - queue que; - que_init(&que); - que_push(&que, &t->root); - - while (TRUE) { - QUE_TYPE node = que_pop(&que); - if (node == NULL) break; - - for (int i=0; ichild[i] != NULL) que_push(&que, node->child[i]); - - printf("%c, refs:%d, fail: %p, output:%p\n", node->data + 'a', node->ref_count, node->failure_link, node->output_link); - } - - que_destroy(&que); -} diff --git "a/\346\217\220\345\207\272\347\224\250/ahotrie.h" "b/\346\217\220\345\207\272\347\224\250/ahotrie.h" deleted file mode 100644 index b494ad5..0000000 --- "a/\346\217\220\345\207\272\347\224\250/ahotrie.h" +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "string_info.h" -#include "linked_list.h" - -#define MAX_NODE 4 -#define FALSE 0 -#define TRUE 1 - -typedef struct _node { - int data; - unsigned int ref_count; - - struct _node *parent, *child[MAX_NODE]; - - int end; - linked_list output_list; - - struct _node *failure_link, *output_link; -} aho_node; - -typedef struct { - aho_node root; -} aho_trie; - -void trie_init(aho_trie * t); -void trie_destroy(aho_trie * t); - -int trie_add(aho_trie * t, string_s * text, char * parent); -void trie_connect(aho_trie * t); -void trie_delete(aho_trie * t); -linked_list *trie_find(aho_node ** t, char text); - -void trie_print(aho_trie * t); diff --git "a/\346\217\220\345\207\272\347\224\250/constructions.c" "b/\346\217\220\345\207\272\347\224\250/constructions.c" deleted file mode 100644 index fe08ab4..0000000 --- "a/\346\217\220\345\207\272\347\224\250/constructions.c" +++ /dev/null @@ -1,109 +0,0 @@ -// -// Created by world on 2019/12/07. -// -#include -#include -#include -#include "constructions.h" - -int comp(const void *p, const void *q) -{ - return ((string_s *)q)->len - ((string_s *)p)->len; -} - -void ConstructSMatrix(string_s * s_i,int matsize) -{ - printf("Accepted input text\n"); - qsort(s_i, matsize, sizeof(string_s), comp); - printf("s_i sort complete\n"); -} - -void ConstructTout(string_out *t_out, char *t_temp){ - strcpy(t_out->str, t_temp); - int i; - for(i=0; t_temp[i] != '\0'; i++){ - t_out->str[i] = 'x'; - } - //printf("Preparing output text structure\n"); -} - -void ConstructTin(string_out *t_in, char *t_temp){ - strcpy(t_in->str, t_temp); - int i,j,start=0,temp_id=-1; - if(t_temp[0] == 'x'){ - for(i=0;t_temp[i]=='x';i++) - start = i; - } - for(i=start; t_temp[i] != '\0'; i++){ - if(t_temp[i] == 'x'){ - temp_id = i-1; - for(j=1;t_temp[i - 1 + j]=='x'; j++){ - t_in->shift_var[i-1 + j] = j; - } - i+=j-1; - } - } - //printf("Preparing input text structure\n"); -} - -/* - - -Link NEW(Item item, Link f, Link b) -{ - Link x = malloc(sizeof *x); - x->item = item; - x->f = f; - x->b = b; - return x; -} - -void ConstructDLL(char s[120], int n) -{ - Item temp; - key(temp) = n; - strcpy(temp.Str, s); - - if (head == NULL) - { - head = NEW(temp, NULL, tail, 0); - tail = head; - } - else - { - tail->b = NEW(temp, tail, NULL, 0); - tail = tail->b; - } -} - -void Assign(string_s *S_temp, Link link_temp, int n) -{ - if (link_temp == tail) - { - strcpy(S_temp[n].str, (link_temp->item).Str); - S_temp[n].len = strlen((link_temp->item).Str); - } - else - { - Assign(S_temp, link_temp->b, n + 1); - strcpy(S_temp[n].str, (link_temp->item).Str); - S_temp[n].len = strlen((link_temp->item).Str); - } -} - -int comp(const void *p, const void *q) -{ - //printf("compared\n"); - return ((string_s *)q)->len - ((string_s *)p)->len; -} - -void ConstructSMatrix(int n) -{ - string_s *S_temp; - S_temp = malloc(sizeof(string_s *) * n); - S = S_temp; - Assign(S, head, 0); - qsort(S, n, sizeof(string_s), comp); - printf("sort complete\n"); -} - */ \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/constructions.h" "b/\346\217\220\345\207\272\347\224\250/constructions.h" deleted file mode 100644 index 59ad708..0000000 --- "a/\346\217\220\345\207\272\347\224\250/constructions.h" +++ /dev/null @@ -1,7 +0,0 @@ -// -// Created by world on 2019/12/07. -// -#include "string_info.h" -void ConstructSMatrix(string_s * s_i, int matsize); -void ConstructTout(string_out *t_out, char *t_in); -void ConstructTin(string_out *t_in, char *t_temp); diff --git "a/\346\217\220\345\207\272\347\224\250/input_win.c" "b/\346\217\220\345\207\272\347\224\250/input_win.c" deleted file mode 100644 index ce775a2..0000000 --- "a/\346\217\220\345\207\272\347\224\250/input_win.c" +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -// #include -// #include -#include -#include "string_info.h" - -// TODO: change here to include your files!! -#include "itoi/grpwk.h" - -int main_prg(int, char **); - -int main(int argc, char **argv) -{ - // struct rusage u; - // getrusage(RUSAGE_SELF, &u); - // struct timeval start = u.ru_utime; - - clock_t c_start = clock(), c_end; - main_prg(argc, argv); - - // struct timeval end = u.ru_utime; - c_end = clock(); - - printf("%f\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); - // fprintf(stderr, "%lf\n", (double)(end.tv_sec - start.tv_sec) + (double)(end.tv_usec - start.tv_usec) * 1e-6); - return 0; -} - - -int sort_f(const void *a, const void *b) { - return ((string_s *)b)->len - ((string_s *)a)->len; -} - -int main_prg(int argc, char **argv) -{ - - assert(argc == 3); - FILE *fp_in = fopen(argv[1], "r"); - assert(fp_in != NULL); - FILE *fp_out = fopen(argv[2], "w"); - assert(fp_out != NULL); - - - - char t[T_LENGTH]; - string_s s[50000]; - //s = malloc(sizeof(string_s) * 50000); - - // input t - fscanf(fp_in, "%s", t); - // for (int i=0; i -#include -#include - -#include "linked_list.h" - -linked_node *linked_node_init(int data) { - linked_node *tmp = (linked_node *)malloc(sizeof(linked_node)); - tmp->data = data; - tmp->place = 0; - tmp->next = NULL; - tmp->prev = NULL; - return tmp; -} - -void linked_init(linked_list *l) { - l->length = 0; -} - -void linked_destroy(linked_list *l) { - while (l->length != 0) free(linked_pop_node(l, 0)); -} - -int linked_search_int(linked_list *l, int data) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter=iter->next) { - if (iter->data == data) return 1; - } - return 0; -} - -int linked_search_node(linked_list *l, int data, int place) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter=iter->next) { - if (iter->data == data && iter->place == place) return 1; - } - return 0; -} - -// insert data to bottom of list -int linked_push_int(linked_list *l, int data, int search) { - if (search && linked_search_int(l, data)) return 0; - linked_node *tmp = linked_node_init(data); - if (l->length++ == 0) { - l->top = tmp; - l->bottom = tmp; - } else { - l->bottom->next = tmp; - tmp->prev = l->bottom; - l->bottom = tmp; - } - return 1; -} - -// insert data to top of list -int linked_unshift_int(linked_list *l, int data, int search) { - if (search && linked_search_int(l, data)) return 0; - linked_node *tmp = linked_node_init(data); - if (l->length++ == 0) { - l->top = tmp; - l->bottom = tmp; - } else { - l->top->prev = tmp; - tmp->next = l->top; - l->top = tmp; - } - return 1; -} - -// look at data of index (negative value for looking from the bottom: -1:=l->bottom->data) -int linked_seek_int(linked_list *l, int index) { - if (index == 0) return l->top->data; - else if (index == -1) return l->bottom->data; - else if (index > 0) { - linked_node *iter = l->top->next; - for (int i=1; inext; - return iter->data; - } else if (index < 0) { - linked_node *iter = l->bottom->prev; - for (int i=-2; i>index; i--) iter = iter->prev; - return iter->data; - } - return 0; -} - -// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) -int linked_pop_int(linked_list *l, int index) { - linked_node *iter = NULL; - if (index == 0) { - iter = l->top; - l->top = iter->next; - } else if (index == -1) { - iter = l->bottom; - l->bottom = iter->prev; - } else { - if (index > 0) { - iter = l->top->next; - for (int i=1; inext; - } else { - iter = l->bottom->prev; - for (int i=-2; i>index; i--) iter = iter->prev; - } - if (iter->prev != NULL) iter->prev->next = iter->next; - if (iter->next != NULL) iter->next->prev = iter->prev; - } - if (iter != NULL) { - l->length--; - if (l->length == 0) { - l->top = NULL; - l->bottom = NULL; - } - int data = iter->data; - free(iter); - return data; - } else return 0; -} - -// insert data and place to bottom of list -int linked_push_node(linked_list *l, int data, int place, int search) { - if (search && linked_search_node(l, data, place)) return 0; - linked_node *tmp = linked_node_init(data); - tmp->place = place; - if (l->length++ == 0) { - l->top = tmp; - l->bottom = tmp; - } else { - l->bottom->next = tmp; - tmp->prev = l->bottom; - l->bottom = tmp; - } - return 1; -} - -// insert data and place to top of list -int linked_unshift_node(linked_list *l, int data, int place, int search) { - if (search && linked_search_node(l, data, place)) return 0; - linked_node *tmp = linked_node_init(data); - tmp->place = place; - if (l->length++ == 0) { - l->top = tmp; - l->bottom = tmp; - } else { - l->top->prev = tmp; - tmp->next = l->top; - l->top = tmp; - } - return 1; -} - -// return node of index (negative value for looking from the bottom: -1:=l->bottom) -linked_node *linked_seek_node(linked_list *l, int index) { - if (index == 0) return l->top; - else if (index == -1) return l->bottom; - else if (index > 0) { - linked_node *iter = l->top->next; - for (int i=1; inext; - return iter; - } else if (index < 0) { - linked_node *iter = l->bottom->prev; - for (int i=-2; i>index; i--) iter = iter->prev; - return iter; - } - return NULL; -} - -// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) -linked_node *linked_pop_node(linked_list *l, int index) { - linked_node *iter = NULL; - if (index == 0) { - iter = l->top; - l->top = iter->next; - } else if (index == -1) { - iter = l->bottom; - l->bottom = iter->prev; - } else { - if (index > 0) { - iter = l->top->next; - for (int i=1; inext; - } else { - iter = l->bottom->prev; - for (int i=-2; i>index; i--) iter = iter->prev; - } - iter->prev->next = iter->next; - iter->next->prev = iter->prev; - } - if (iter != NULL) { - l->length--; - return iter; - } else return NULL; -} - -void linked_print(linked_list *l) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter = iter->next) { - printf("(%d, %d) ", iter->data, iter->place); - } - printf("\n"); -} - -int linked_delete_int(linked_list *l, int data) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter=iter->next) { - if (iter->data == data) { - linked_pop_int(l, v); - return 1; - } - } - return 0; -} \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/linked_list.h" "b/\346\217\220\345\207\272\347\224\250/linked_list.h" deleted file mode 100644 index 4627624..0000000 --- "a/\346\217\220\345\207\272\347\224\250/linked_list.h" +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -typedef struct _linked_node { - int data, place; - struct _linked_node *next, *prev; -} linked_node; - -typedef struct { - linked_node *top, *bottom; - int length; -} linked_list; - -void linked_init(linked_list *l); -void linked_destroy(linked_list *l); - -int linked_push_int(linked_list *l, int data, int search); -int linked_unshift_int(linked_list *l, int data, int search); -int linked_seek_int(linked_list *l, int index); -int linked_pop_int(linked_list *l, int index); - -int linked_push_node(linked_list *l, int data, int place, int search); -int linked_unshift_node(linked_list *l, int data, int place, int search); -linked_node *linked_seek_node(linked_list *l, int index); -linked_node *linked_pop_node(linked_list *l, int index); - -int linked_delete_int(linked_list *l, int data); - -void linked_print(linked_list *l); \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" deleted file mode 100644 index 84431dc..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" +++ /dev/null @@ -1,180 +0,0 @@ -// -// Created by world on 2019/12/07. -// -#pragma GCC optimize("O3") - -#include -#include -#include "../constructions.h" -#include "BM.h" - -void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s_count, linked_list *t_opt) -{ - /*----------------------initialize-------------------------*/ - int t_id, esc, comp_var, point, t_len = strlen(t_in->str); - string_s *s_i; - - /*---------------------------------------------------------*/ - for (int i = 0; i < to; i++) - { - s_i = &s[i]; - //t_id:s_iの最後尾がいる場所 - t_id = s_i->len - 1; - //esc:一致した文字の個数 - esc = 0; - //comp_var:何回比較したか - comp_var = 0; - //point:比較済みの文字の中で左から見てxに最も近い場所 - point = t_id; - int table[110][4]; - - /*---------------------makeShiftTable----------------------*/ - for (int k = 0; k < s_i->len- 1; k++) - { - int Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][0] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][1] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][2] = Tcounter; - rep(j, 120) - { - Tcounter = j; - if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) - break; - } - table[k][3] = Tcounter; - } - /*---------------------------------------------------------*/ - - while (t_id - 1 <= t_len) - { - int flag = 1; - //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ - if (t_out->str[t_id] != 'x') - { - t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); - point = t_id; - } - - //s_iが指定位置t_idにマッチするか確認 - int branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); - if (((t_in->str[t_id - comp_var] != 'x') && branch)) - { - //failware - flag = 0; - esc = 0; - } - else if (!branch) - { - //success - esc++; - comp_var++; - } - else - { - //ignore - comp_var += t_in->shift_var[t_id - comp_var]; - point = t_id - comp_var; - } - - while ((flag == 1) && (esc < 23) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) - { - if (t_out->str[t_id] != 'x') - { - t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); - point = t_id; - } - /*----------------------DebugPrint-------------------------*/ -/* - printf("t_s:"); - int j; - for(j=0;jstr);j++) - printf("%d",t_out->shift_var[j]); - printf("\nt :%s\n",t_in->str); - printf("out:%s\n",t_out->str); - printf("s_i:"); - - for(j=0;jlen+1;j++) - printf(" "); - printf("%s\n",s_i->str); - printf("cmp:"); - for(j=0;jstr[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); - if (((t_in->str[t_id - comp_var] != 'x') && branch)) - { - //failware - flag = 0; - esc = 0; - } - else if (!branch) - { - //success - esc++; - comp_var++; - } - else - { - //ignore - comp_var += t_in->shift_var[t_id - comp_var]; - } - } - //マッチした場合t_outに挿入,そうでないなら次の場所を探索 - if (flag == 1) - { - if (s_i->len > 22) - { - int x, y; - for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) - { - t_out->str[t_id - y] = s_i->str[x]; - t_out->shift_var[t_id - y] = s_i->len - x - 1; - } - t_out->shift_var[t_id - y] = s_i->len; - esc = 0; - goto next; - } - else - { - linked_push_int(&s_count[s_i->id], t_id - s_i->len + 1, 0); - for (int j = 0; j < s_i->len; j++) - { - linked_push_node(&t_opt[t_id - s_i->len+ 1 + j], s_i->id, j, 0); - } - } - } - int temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, - table[comp_var][t_in->str[t_id - comp_var] - 'a']); - - t_id += temp; - comp_var = 0; - point = t_id; - } - next:; - } -} diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" deleted file mode 100644 index 3e7a00f..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../string_info.h" -#include "../linked_list.h" - -typedef struct Node *Link; -struct Node{ - int *id; - Link b; - int *x; - int *count; -}; - -#define High(A, B) (A > B) ? A : B -#define rep(i, n) for (int i = 0; i < (int)(n); i++) - -void BM(string_out * t_in, string_s * s, int to, string_out *t_out, linked_list *s_count, linked_list *s_opt); diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" deleted file mode 100644 index b4140c1..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -#include "../constructions.h" -#include "grpwk.h" -#include "itoi.h" -#include "BM.h" -#include - -// input_win.cから呼び出されるやつ -char *grpwk(char *t, string_s *s, int len) -{ - /* 文字数の区切りを決定 */ - int bm_until, aho_until; - for (bm_until = 0; bm_until < len; ++bm_until) - if (s[bm_until].len <= BM_TO) - break; - for (aho_until = bm_until; aho_until < len; aho_until++) - if (s[aho_until].len <= AHO_TO) - break; - - /* BMはじめ */ - string_out *t_in = (string_out *)malloc(sizeof(string_out)); - string_out *t_out = (string_out *)malloc(sizeof(string_out)); - - for (int i = 0; i < T_LENGTH; i++) - { - t_out->str[i] = 'x'; - } - t_out->str[T_LENGTH] = '\0'; - ConstructTin(t_in, t); - - // init option lists - linked_list *t_opt = (linked_list *)malloc(sizeof(linked_list) * T_LENGTH); - for (int i = 0; i < T_LENGTH; i++) - linked_init(&t_opt[i]); - linked_list s_count[len]; - memset(s_count, 0, sizeof(linked_list) * len); - ; - BM(t_in, s, bm_until, t_out, s_count, t_opt); - printf("bm done\n"); - - // int err = 0; - // for (int i = 0; i < T_LENGTH; i++) - // err += (t_in->str[i] != t_out->str[i] && t_in->str[i] != 'x' && t_out->str[i] != 'x' ); - // printf("err:%d\n",err); - for (int i = 0; i < T_LENGTH; i++) - { - if (t_out->str[i] != 'x') - { - // if (t[i] != t_out->str[i]) - // { - // printf("error: %d\n", i); - // usleep(10000); - // } - t[i] = t_out->str[i]; - } - else if (t[i] == 'x') - t[i] = 'a'; - } - // return t; - - ahocoralike(t, s, bm_until, aho_until, t_opt, s_count); - printf("ahocora done\n"); - - linked_list s_opt[100]; - memset(s_opt, 0, sizeof(linked_list) * 100); - // s_opt init - for (int i = 0; i < aho_until; i++) - { - s_opt_insert(s_opt, s_count[i].length, i); - } - - /* delete options where t is already determined by BM */ - for (int i = 0; i < T_LENGTH; i++) - { - if (t_out->str[i] != 'x') - { - discriminate(i, t_opt, s_opt, s_count); - } - } - printf("discrim done\n"); - - /* TODO: test */ - // for (int i=0; ilen; i++) - { - discriminate(s_pos + i, t_opt, s_opt, s_count); - } - - /* insert text to ans */ - for (int i = 0; i < text->len; i++) - { - // if (t_out->str[s_pos + i] != 'x') printf("eorro\n"); - t_out->str[s_pos + i] = text->str[i]; - } - } - - for (int i = 0; i < 100; i++) - linked_destroy(&s_opt[i]); - for (int i = 0; i < T_LENGTH; i++) - linked_destroy(&t_opt[i]); - free(t_opt); - - for (int i = 0; i < T_LENGTH; i++) - { - if (t_out->str[i] != 'x' && t_in->str[i] == 'x') - { - t[i] = t_out->str[i]; - } - } - - free(t_in); - free(t_out); - return t; -} diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" deleted file mode 100644 index d8f02f2..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "../string_info.h" -#include "../linked_list.h" - -#define BM_TO 16 -#define AHO_TO 11 - -char *grpwk(char *t, string_s *s, int len); diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" deleted file mode 100644 index 79e4da8..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include - -#include "../ahocorasick.h" -#include "itoi.h" - -// outcome functions for testing -void callback_add2linked_list(ahocorasick * aho, linked_list *l, int pos) { - linked_node *iter = l->top; - for (int v=0; vlength; v++, iter = iter->next) { - string_s *text = &aho->s[iter->data]; - - // s_count[i].append(text.pos) - linked_push_int(&aho->s_count[iter->data], pos-text->len+1, 1); // <- index of first letter - - // t_opt[i].append(i, place) - for (int i=0; ilen; i++) { - linked_push_node(&aho->t_opt[pos-text->len+1 + i], iter->data, i, 1); - } - } -} - -// 入力されたintの中で何個のビットが立っているかを返す -int bitcount(unsigned long long bits) { - bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); - bits = (bits & 0x3333333333333333) + (bits >> 2 & 0x3333333333333333); - bits = (bits & 0x0f0f0f0f0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f0f0f0f0f); - bits = (bits & 0x00ff00ff00ff00ff) + (bits >> 8 & 0x00ff00ff00ff00ff); - bits = (bits & 0x0000ffff0000ffff) + (bits >> 16 & 0x0000ffff0000ffff); - return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); -} - -// bitchangeにおいて立っているビットの場所の文字を'a'に置換する -void convert(char *tmp, char *s, int len, unsigned long long bitchange) { - for (int i=0; i> i & 1) tmp[i] = 'a'; - else tmp[i] = s[i]; - } - tmp[len] = '\0'; -} - -// アホコラを使用したあいまい検索の関数 -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count) { - /* おまじない */ - ahocorasick aho; - aho_init(&aho, s); - aho_create_trie(&aho); - aho_register_option_lists(&aho, t_opt, s_count); - aho_register_match_callback(&aho, callback_add2linked_list); - - char tmp[120]; - - for (int i=from; idata].length == 0) { // same as the insert option - free(other); - continue; - } - - // go to s_count[other.id] and delete the option to insert here - if (linked_delete_int(&s_count[other->data], t_index - other->place)) { - // reinsert the deleted option to s_opt - s_opt_insert(s_opt, s_count[other->data].length, other->data); - } - free(other); - } -} \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" deleted file mode 100644 index 7c9962f..0000000 --- "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "../string_info.h" -#include "../linked_list.h" - -void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); - -int s_opt_insert(linked_list *s_opt, int s_count, int index); -void discriminate(int t_index, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); diff --git "a/\346\217\220\345\207\272\347\224\250/queue.c" "b/\346\217\220\345\207\272\347\224\250/queue.c" deleted file mode 100644 index b746f52..0000000 --- "a/\346\217\220\345\207\272\347\224\250/queue.c" +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include "queue.h" -#include - -void que_init(queue *que) -{ - que->data = (QUE_TYPE *)malloc(sizeof(QUE_TYPE) * MAX_SIZE); - que->front = 0; - que->back = 0; - que->size = 0; -} - -void que_push(queue *que, QUE_TYPE value) -{ - if (que->size >= MAX_SIZE) - { - printf("キューの容量がいっぱいです\n"); - return; - } - que->data[que->back] = value; - que->back = (que->back + 1) % MAX_SIZE; - que->size++; -} - -QUE_TYPE que_pop(queue *que) -{ - if (que->size == 0) - { - // printf("キューの中身は空です\n"); - return NULL; - } - QUE_TYPE top = que->data[que->front]; - que->front = (que->front + 1) % MAX_SIZE; - que->size--; - return top; -} - -void que_destroy(queue *que) { - free(que->data); -} - -// void printQue(queue *que) -// { -// int i; -// printf("data : "); -// for (i = que->front; i < que->back; i++) -// { -// printf("%p ", que->data[i]); -// } -// printf("\n"); -// } diff --git "a/\346\217\220\345\207\272\347\224\250/queue.h" "b/\346\217\220\345\207\272\347\224\250/queue.h" deleted file mode 100644 index cd892a7..0000000 --- "a/\346\217\220\345\207\272\347\224\250/queue.h" +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "ahotrie.h" - -#ifndef QUEUE_H -#define QUEUE_H - -#define QUE_TYPE aho_node* -#define MAX_SIZE 8000000 - -typedef struct -{ - QUE_TYPE *data; - int front; - int back; - int size; -} queue; - -void que_init(queue *); -void que_push(queue *, QUE_TYPE); -QUE_TYPE que_pop(queue *); -void que_destroy(queue *); -// void printQue(queue *); - -#endif diff --git "a/\346\217\220\345\207\272\347\224\250/string_info.h" "b/\346\217\220\345\207\272\347\224\250/string_info.h" deleted file mode 100644 index ba95f16..0000000 --- "a/\346\217\220\345\207\272\347\224\250/string_info.h" +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -typedef struct { - char str[120]; - int len, id; -} string_s; - -#define T_LENGTH 400001 - -typedef struct { - char str[T_LENGTH + 1]; - int shift_var[T_LENGTH]; -} string_out;

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 diff --git a/main.c b/test_main.c similarity index 100% rename from main.c rename to test_main.c From ffdbb60a71b4180cb466a872877d96a3de862f36 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 22:45:30 +0900 Subject: [PATCH 33/37] =?UTF-8?q?=E4=B8=AD=E9=96=93=E8=A8=88=E6=B8=AC?= =?UTF-8?q?=E7=94=A8(checked=20by=20itoi)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middlesub/grpwk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index 2cbbce8..a316dbc 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -142,8 +142,7 @@ char *grpwk(char *t, string_s *s, int len) for (int i = 0; i < T_LENGTH; i++) { if (t_out->str[i] != 'x') { - if (t_copy[i] != 'x') t[i] = t_copy[i]; - else t[i] = t_out->str[i]; + t[i] = t_out->str[i]; } } From 025064d2fc3cf9cc263f52440617667ac6edd7cb Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 22 Dec 2019 23:01:43 +0900 Subject: [PATCH 34/37] Makefile --- Makefile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f3bad14..6c5a5ba 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,13 @@ PROG = grpwk -OBJS = input.o +SRCS = input_win.c ahocorasick.c ahotrie.c constructions.c linked_list.c queue.c middlesub/BM+.c middlesub/grpwk.c middlesub/itoi.c CC = gcc CFLAGS = -W -Wall -Wextra -Wconversion -Wshadow LDFLAGS = +OBJS = $(SRCS:.c=.o) -.SUFFIXES: .c - +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ $(PROG): $(OBJS) $(CC) $(LDFLAGS) -o $(PROG) $^ -.c.o: - $(CC) $(CFLAGS) -c $< clean: rm $(OBJS) $(PROG) \ No newline at end of file From 68bd06edf05354993fc41cd6cb2f5b1e1bf44ab0 Mon Sep 17 00:00:00 2001 From: udemegane Date: Sun, 22 Dec 2019 23:21:32 +0900 Subject: [PATCH 35/37] =?UTF-8?q?=E6=8F=90=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- a.out | Bin 0 -> 12696 bytes data/dat0_out | 1 + middlesub/grpwk.c | 10 +- "\346\217\220\345\207\272\347\224\250/4.tar" | Bin 0 -> 130560 bytes .../Makefile\357\200\272Zone.Identifier" | Bin 0 -> 27 bytes .../ahocorasick.c" | 74 +++++++ .../ahocorasick.h" | 31 +++ .../ahotrie.c" | 160 ++++++++++++++ .../ahotrie.h" | 34 +++ .../constructions.c" | 109 +++++++++ .../constructions.h" | 7 + .../input_win.c" | 68 ++++++ .../linked_list.c" | 209 ++++++++++++++++++ .../linked_list.h" | 28 +++ .../middlesub/BM+.c" | 180 +++++++++++++++ .../middlesub/BM.h" | 17 ++ .../middlesub/grpwk.c" | 156 +++++++++++++ .../middlesub/grpwk.h" | 9 + .../middlesub/itoi.c" | 98 ++++++++ .../middlesub/itoi.h" | 9 + .../queue.c" | 52 +++++ .../queue.h" | 25 +++ .../string_info.h" | 13 ++ 23 files changed, 1287 insertions(+), 3 deletions(-) create mode 100644 a.out create mode 100644 "\346\217\220\345\207\272\347\224\250/4.tar" create mode 100644 "\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" create mode 100644 "\346\217\220\345\207\272\347\224\250/ahocorasick.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/ahocorasick.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/ahotrie.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/ahotrie.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/constructions.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/constructions.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/input_win.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/linked_list.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/linked_list.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/BM.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/queue.c" create mode 100644 "\346\217\220\345\207\272\347\224\250/queue.h" create mode 100644 "\346\217\220\345\207\272\347\224\250/string_info.h" diff --git a/a.out b/a.out new file mode 100644 index 0000000000000000000000000000000000000000..05a48db6e492ff6cb59b5682e1119d4b794331fd GIT binary patch literal 12696 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 DdsB2I literal 0 HcmV?d00001 diff --git a/data/dat0_out b/data/dat0_out index e69de29..5911ab5 100644 --- a/data/dat0_out +++ b/data/dat0_out @@ -0,0 +1 @@ +baaaaaaaadadacbbxxaacxdxxdbdxaabdxadadabaxadaxabbxbdxadaxaxxxxdbxcadddxadaaaabxbxxabaadaxbddbdacdaabaadbdadadbbxxbaaaaxdaadxxdxxaaadbdadbacbaaacbbccaxxaxxccbxdbdacbabbdbbcabadbxabbcxacdacxdxdxxaaxxacxbbxxccabaaaacaadbbcbcaadbdaacdaacdbdadabxbxxdxaxxxxbdbacaaadbbaaabbdaadbacadbdbacbaaaxxbabaddbdxxbxdaaaaaadbcaabdbdaaacdbacbbddaaxbabbaxbxbxbxxxbxaaaacdbbcbbbdbdbaacaaaccdabbxxcxxxbaxbdbaaadbaaabbdbabadddacdaacacaabbabaaadaacdbbbbbdbaaaadabaacadaaxxacbaaadaaaabcadaadacdaccaadacccdbbbaacbdaddadaxcdxcdxxxxbbadabdbaaadabbdaabaaaaadabaaadabdbadbaaaaacaaacbaxabdbbaaaaadaabdbacdaacdxdaxbdaxacxdaxxdaxxxxdxdbacdxxdxaxaxdbdxbxbdacxxadaacxxdaadadaaxaaaacdbbabdbadbacbaadbbcdxdxaadbaacxabxacdabdbaddbacbadbdaxadadxdbdaxxxcaxxbaxaaaabdxxaabaxxxxbaxxdxxdbxxccxaddacaccbabadbdddbdbacdbbdbxaxxxbxdaabxxabaaxxbxbadaaaxcdbbaxddbddbbaaacaaacdacabdadaxxxbxadxaxcxacxxbcaxcdbaxxxxdxbxdxcbxaxcxxaxdabxxadaxadbdxxxcxaxxdabaaabaxacdxxxxxaacabaxxcxxxcxaaadaxdbaxbxbxaaaxxxxaxxbacxbaxcxabdaaaxaxxabxcxcxxaaxxaxbcxdxxaaabaaadbbaaacadadbdaacacbabaaacaabddbdbbbbdaaaacxxxdbadbabaaxxacddaaadaaaadaaaaxcaabadbdaaaadadaadaadbdabbdadaaaaxaaxdxabbxxadaaxbdaaccbcbdaaaxdbdxxdxxcdbxcbxaaacbdxxdxxabdxaxxdxadadxbaxbaxxxbdxxxabbxcbdbdxaddaacaabdbbbdbadaaccdaaaabxdxcdaxdabdbabdabacbcaaadabdaaadacdbdabxbabxxxabaxxxcbxdxxxcxxbxdbbdxaxxxxxbxaaxxbdaacabdbadabdbabdbcbdxbbadbaadabbcdbbaadaaabbababbacbdbaaaacbdbacdxxbdaxadxxaxbxxbacxddabdaaadacbdacbaaadaaxcxbxcdbdaxxcbaxxcaxbxdxdadaxxbabbxxdaaabcbaaacbdbaaacadaabbbcadbdacbbaaacxxadbdacbdaadaccdbacadxbxdaxaaaaxacxxaxababdbdbacdbbadacdaaadxabxabbxacdaaxaaabxxxdbdddaaacxxdxacaabcaccaaacaaaddaabacbbaaaadacaddbadacdabxxxcxbxabxddbabxxxdaxaxdaaaacxxdxabxbxbdbaxdadxxdbaxaxbababcabxxdaxbdxbbbxaadbaaccdbdadabadbaddacabxdaddbbdabdbacacabdbxbdbddbdbaaaadbaxaxaacxxaaxbxbcxaxaxaabaxaxbdxaaxdxbdaxbxacxaxaaxbxabxxxbdbxbaaabdxdaxadxxaabbbdbxxabdbacdbaabccbbaabdacbcdaxabxxacbxaxbbxbdacabadxabcaaaaacbaaaabdaxaxaaaxxxxddadbxxxbcdadbdbdadaabbdadaaccbddabxxaxaxdaxdxxbxxxxbxbabxbxxxxbadacdaaadabdbdabaabadadbbdxxxxbdbxxadxdabbdbbaadbdaacdaacbdaadbcdbbdbacbbaaaabcbaaaaaaacdbcbbdadbbdaaaadbdadaabadbabdadbaacaacabdbaxcxdacxaaxcxxadbaxadxbxadaxbxabbxbaabbacbaxxxxaxxcxxxaaacdxxbdaccaxxxaxdbdxadxxaaaabxbaxaxdxbdbabbdabddadaadbbbaaaabdbdxxccdxbadxxxbaxbxadxxdxxaxxaxxdbadbdaaadbaaaaaadbacbbbcacdaabdxdaaababcbabacdbacaadaabdacabbbadxxxdbaxxaxaaxxcbxdxxbdabdbdaaacdaaaaadbabaccdaxababxxdxxbxxxxxxadacbdbaadbdbadaabadxxbxdaadadxxxbxxaadbdbabdaaaaaccbdbabdacaaabcdbdadaccabxdxxdbaadbdxadabddacaaaabcxbdbaaadbaddaaabdbacdaadxxdaccxaaxbdxdxdbaxxddbcacdaddaadbddbbacbabdabcbcbaadacdababbabaaaaabdxxabxbxaxaxxxcaccabxxxacbbbacdbdbaccabbadadabbaxcxaxdaaxdadbacdbbbbabacbcaacbaccccadbabaaadaaabaxdbaacdbdbbddddbadabxadxddbdadbdbaddbdacdbdbaadxacxaxxxxbbadaxxbdxxddxbxxxxdxdabxbdacxdbcdbdxcxaaxcaaadxxxxbdacbdbaxacdxabadaaaadaxaxxxbaxcaxdxaacdbxaadbadaaabadbbdbbbdabdbdbadaxaxdxbxbaxxxbxxaabdadaaaacdababdbdbbdaaaabaxadxxaaxxaxxxxacxaxdaabdxxxxxaaababcabacdbbadadaadabaabdbcdadaxaxdaaacabcdabdbdbdbadadbdacbdbaacaacbacxbabdxadadbdxxbxaacxxccdxdadxxaadacccbaddbbbddabadadbcdabababbdbdadaaacbdadaaddabdbdacbaabaaaadbbbdacddaaaaccbdbccaddabacadbbbxaaxbxxdbdaaaadbabaaacdbadbacbbadbaxxxabxxbxdxxaaxdabxdxxdxbaaaaxdabaacdaaabdbdddadbcdbacabaaaadadbdadbcabacbcaxacdaaabdbaadbcbababbdadaaacdbcbaaababdacdbdaadbcdbdaadaaaxbdxcddbbbddbbaadaadaaacbaacxbxxdxbxdbaxxcdacaacdbxaaaxxaccbaaadbdbacabaacadbxcababdbbddbaacbdacaccaxdxdxaxdaxdbxabxaxadbaaxxxxcxxxaxcdadbbdbaaabaabdbdbadaadabdxbxxbxdxdaxdbxaxdaxaxxxaxaxxxaaabadaaaaabacdbaaaabdacdabbxbaxadbacbadaaaaaacaaababaccbaxxbdxxaxxbaaxxcbaxabdbbabdbacbabaadbdbdabaabaacxcbadbddbxdxxadxxdxxxxaaxadaxbxxxxacbxxccbxxdbxxaadaaadbbdadxaxxbbbxxaxxxdbdbababxdxdxxaxbxxabxbcababaacbacabcdabbaadaabdadadacacabdababdaadbabbcdabdabxcaaxbabdacabdabddbddaaabbdbdbbbdxxbacdaxabxaxaaxxaxbacaxbaacxbdxxxaxaaxbacxbbxaxxdbdbxxxxdacaxxcdaaaaacxadacdxcxdbxdaxdxaxdxxcbdaxbxxbaaxbabbaadaxdxdxdxdaxxaaaaxxdxxbaxcxacacxxxdxxxdadaaadxxdxacaxdxdabxadxbacdadabdaccdbbcbdbdaacbabacababdbbdbadbbbbdaaaaxaabxdaaaababbbabdbabadadbcxbdxdxaacxxcacdaaadaabdaccabbcaabaaabcdadbbbdbbdbabaxxddacccadaaadaadababdaadaaxdbcxxdbbdaacdbaxaaddxcbxxcdbbddabbacbacdadbcccdddaaaabdadbdbabdaadbdbbaaaacaacxxxdxdxddaxxdaxaabbacddadbdbaaadaddacbdbcaabbcdadaddabaccadbddxacbbxxxbxaxacdbbadbbbbaacbaaaacdbdaababcbaacbbdbbaaccbbaadabbdxabaaxaxxxbacxxxxdxxaaxbbxcbxbbxadbadbaxaxaxddxdaaaacbxxbxacacadaacddadaaaabadbxbxaaaaxdbdaaaababaacbcababaaaadadbddabbbcabaccdaaaabacdbaabbbbbbcaaabadbdacdaaaaadaaabbbaaacbcbddadaabaaaabbbdbdadacbdbbbabbaadbxdxxadxcbdaxxabaaabdaaxxacxxdbxaaxxxacddbacbaaaacbcdaccdbacdacacbaaccxaacaaxbbacaabcabbbbdbbcacbbadbacababbxdaxbdxaxxdbaxdbabadbaaaddbdadbbacbdadbbdabccabaadadbdbabbaaaddaaadddabcbabdabdaacdbcdaabbbaabaaababadxbbacdxxcbxacbxaabaabdbcdbadaaaaabdbdaxxbxaadxxbaxaxadaacaxxdbdxxdbaxbabxbbabaaxaccxxbxaxdacbcdaccbdacdbdacaabccbdbdbdaadaaaaaaabbdaadacabccabdacbacbbdbdbaabbbdbdbbxxbbaxxaxbxxdbddxabxxbdbxabxxxaxbxbxaxaacdbxxaadadxadacxaxbaxcxxbxacxaxdxaadbddaaadbabaadaabacbxxdxxbdbxaxdxxxaadxbaabbacdaadadaadaccdbddbbdxcxxxcadbxabaxaxabaxxxxcaaxxaxxbdbadaaadaddacdaddaaxdaxxbdxdaddxdaxxabxcxxdaxcdadxxxxacaadxaaacaxxdxxadaxaabxxxxaxacabbddbdbddbacadacxbxbbabxxbxxxadxcbxxbdddxaxdbbbdacdbdacbaabdcbbxdxxxaxxxaaxxxcaadaaaabdbaaaaaabcbdbabdabdaxaxxbaadaaddbdaabcddadadbddbbdadxdbbabaacacdaadbddabdadbacdbbaacdbbaxaxacxxxcxbcbaaacbadbaaaadaacdbbbcbbcdaadabaaadaaaaadaacadddaadaabxxdadabxxxxabaxdbadaaaxbxaabdbdbaaxxcxddbcacbbabbbadaadbdbcdbdadacbdbdabdxxcxdxxaacdddxacbdaaabdabaacaaaabaabxcxxdaxbxxddxbxaxddxcxbacdadbabxxaxacdbdbcdadaaadbaabadacbadaaacadbcbbaxaxxbxbxdxadaadbdadabdbdaccbccdacbxbxdbaxaabxbdxcxxxdbxabxabbbaxxbdxxbaxbdbxxacxadaxxxbaxxxbxdadacaabdbadadaacdadadbdaacdaadaxxxxadbbaxbdxxdaxbxaxcdxxxbabxdacccxaacdaxdbcxadbdbdxxbxxbxdxaxdxbaabaxaaacaabadaaabddbdbdacdbaxxacxxccaababaaaabaabdxaxbxbdxdxxdabadxdaxdabbaacdaacdacbaccadabxxxadbddbxadxxadaaacdbcbddbdaabcbbbbbaaccdaababdabaabdaccdbddbcddbbaxaxdacaxxabaddbdbdbdadadaacadabbbaaaaxdacdxxadbcbabdbbaaacaaaadbbcdadbbadxaxadxdabbdbaaaccabdabdbadbbdbabaaabaadbdaabbdbacbabcacdaadbbaacaadbbcccbddbdadbaacacbdbcabaadbcaaxdxbabddbacdadbbaaacdbbcxxaxadbxxxbaxdacxxxbxxdxadbdxdxcbddbdaaabbaaaacbabcaadbbaaaacdbdaaaxxxbdabadacdbdacadaaaaacdaadbbdxxaxxxbxbdxbxdaxxxxbdaabdxxdaxdbxxxbaxxxbabaxaxacbdaacaacdxbdbcaacdacbbcdbacbaadbaacdabdbcdbbaaacdaaacbaaaaxxbxbbxxadadabaaabdbaacbdacadadabdbxabxxdaaxbcxxdadadabdaaacbacdbdbbabddaacdaaaaabbddbabxbdxdxxxadbaaxdxxxaxxdbxcaxxxaxxaxadabdabdaccdbbbdadbdabaacabaccaabdaccbxxxxacdadabdbcadadadaccbbaabdadbababdbbdaaaabdxaaxxxbaxxaadbacdacdadbdaaabbaaaddbdbbcbbdacbdbacadbabadbbbdacbbdabdcdbadbabaacbacdabacaacxaxxxxxxcbabdbxxaabacacdaadaacbaaadaccabxxdbdbacaacddaadaaaacdxxcbxxaxdabbxaxxbacdbdxxdxbxxbdxcbxxxxbdaadabdbdaaaababadadacdaabcbxdbabaxxxxxdxdbcaxabbxbdbbbcbdbbbacaadaaaadabdaacaaadabdaxxcbbdbacdadbdbacdbdabdbaababaaaaaacdabacbbdbcbaadaacaacbabdabaadbdabaxabdxcxbxbxaxxdxxaxaaaxdaxbxdxdabbbbddaaaaadaddaaaacabaacbaddaadxaadaacbaaabbbcdabcbaddabcdacdacbdabadbbcdbbacdaxxxxxaadabbxaxxbaxxxxxxbxxdaaacadbadbbbadadbbbdabdbcbadaadabcaaacdacacdbacxxbxdxxxdaaxabxxcbaaxxdadxacbcdabccdbaacdbcdacabadaaacdddaxxaxxaaacdadbdbdbaabacdddadbbxxxxcxaxcxxaxcddaxaxaxxxxbaacdacdacdbadadbdadadbaaaacbdadacdabacbabcxxdacacbabcdbaxxxaadxxxcbxaaxaxbxcxxcxxbdxxaxaaxxxdxaxaacbxaddxacacdbdacdaadbaaddbaxaxbcxdbdxbcxxaaccxxbbacdaaadbabcdbdaababbbaacdbbdaaabdaxxbcacdxxxdbacdbdaaaadabdbbbdabababacddbaabdacabbxxddacdabddabdaacaaabadaaxxaxxxcacxdxbdbddxxdbbaaaaadbaabdddadadbaaaadaabxbbaxdbbaaxbdbxxxcxxdaxxabdabdaacaadabbdaaabadaadacdbdbxbacdbcdbacaabadadbacabxabcadxxxxdbxxaxbccdaxaxbcdbaadaaaaadbdacdbacxaxxaadbdxcxbcxaaxdxxxaaabccabadbadaaabdbdababadxxcxxxacxbxxxxxcxbxbbxcxxdddbdacaadabacdaaabcxdbbxdaadbbxdbdbbababbabdbabbabdxcadbbbbcbdaacdadbdabdxaxabxxbxaxdbxxaxdxaadxaaaxcxaaxdxddbdaacdbabaacddacacdbaaaaadaaaxxxxabbbbaxadxcdxdxdabbcdaaadadabcdbxdacaaxxxxacadaxcacdxxacxxxbabdaacdxaacxxdbdbdacadaaaaabdadacbaabacdaadadaaaxaxdxxdxdabadbddaabadbddbbdadxxbabcxbacxxacxbxxdaxbbaabadbacdaacadadaddabbdabaaacaaabbcaabddbdaabdbdadaadacdaaddabcbbbaadbbabbbdbdbaacdadabxxaacbcbdaaaaxxxxdbbacxxaaxxacaaaxcbxaxxaxddxbbbabxdxdxdbxxbxxxdxxxbcxxcxadbbdadbcdacbaacbbaacbaxxcccbbxcbxaxacxxcxxcabdbbacbacbacacacbbxaxxxbxxcdaadbbcdbdacdabdabaabbdadbcbacdbbbaacdbxxadabdabdbaxadaxcdaxcxxxdbxaxxxbdxxbdaxaaabxbxxxdababdxdacaxcbabxxdaaaxxdxxxdxaaadxbxbacxxxaxbabxaxddbdbadbabdbaaacbcbbdbdaadbdbcabdxxdaacdbxbacbdbacdbcbddaabdxabxaxaadbxadbaxxbdacxdadbbacaaccaaacaaaadacacdadabaadacaccbbbdacdadaadadbaacdaadadaaabacacdbdxbdxxcaacbbabxdacxxxxdxbdbxbxxxadbabxdbadaababaababbdbadbxacaxabadaaxxacaxcdxcdxxaacabxbxxxaxaaabdabbdbadbcdadacbcddaxxaxxxbxxacbadbbbdbaacdabcaxaaxcxadaxcadbbbxaaaxxxddbxdbxaxcddbbdabdaaabacbabbabbbcbbxxxaxaxccbdaadaadbacadadaaaaadbacbbdbacbaaabbaddxaxdbdadxbcdxxaxxcddxxxaxxbbadbcbbdaacaacdbadaababdbbdadabaddbabbbaadaadacabaccaadxadxacxxxaadbdabaadacaaaacbxaacddbadbdxxaxaacaaacacbcbdabcdbaaaaaadbdaadddbaaababdbaaaddbaaacbbbadacdacbdbacdaccaadaacadadbdaaacxxbxxbcxdaxxbbbdbbaaababadaaacadbacdaabdbacbaaadadaabacacaccbbxdbxxbxcxxbxacxacxxxcbxxbaadaacdaadacdbbabcadaabxxxbxxdxdxccaxcaxbdbadacbccbdaaababdxaxaxbxcxbxaxxacxdbcxbxxxbcabaacxaaaabxbdbdxcxbdbaxdadbbdbbdaabadbaadbcbacddabdbbdabadbbaaaaacdabxadbacdxdbdxbacaaaxacbaddababacadbaaadbdaaaaabdababaacddbabbabdacaaabdbbabbbcbdadbacadbdxcxaxdxdbbbdxbaxxxabaabbdbacbadaaaacbdbbdaacbdbdxbabbcbaxxaxxxaxxaxdadabaadxdaacxaaaaxxaacdaaabdababcdabbacabcbadaacdbaaxaaaxdxxadbxbxcxxxaadacxxbaxbdaadbxxxxxdbbaaccabadxbaxaxaxaaxaxddbxxbxxacdaxbadxxdbdaacdaaaacabcbabaaaacaacdbdbcdbcabaaaaacbaxxaxdxcbxxaaxaxxdadxaaaaabdbbbbcbcbbaaadbddbbaaaaddbbbdacaadaaaadacbaacdbdacddacddbadaaxxbbcxxcxbadbaxdaxxaxacxbbcbbaacacdadacddabdababxbadaacbabaaxxaaxdxxaxxcdxbxxabdbbcaxxabaxxxxbcxxdbcxbaacdbcbdbbbbcdaadbabadaxadxdbxdabxbaaaxxaxdbcbxxxaaxbdxacbdbbccbbabababbbacdbxdacxbadacdacdbdbdbdbdbaccbaxdacxadxxxbddxbadbbcdabxabxxxadaaadacaddaabaacbbadacbaaadbddabdabdacadbabdbcdaacabaacddbaaaxxcxacdaxbxxaaaxxxaabbdacabdbaabxxxxxdbdxaxxdaxbadbxxdbdbacdbbdabaaaadbcababbdabaadaadbabaaaaaaabdbabddaxaaxaadbadxbddxxxdaaxadbxadxaxxdxbxbxxxacaaxadxbdbadbdaaababadabacbdaxabdxcxaxaxxbxaxxbxcddbxaaxbaxbadxcabaabaaadaaaabdadbaaaadbdbabcbbadacxxxcdxcbaxxbbxbadxxaxbadxxdxaaacdaaaaaaabaaaaaadbxaaabaabaaaaacdbbbaaaadaaxdacxaaxxxaadbadadbbadaaaadbaabacaadbababbbaaacbabdbdaaacabdadxdaxadbaxxcccxxcbdxxbxccaadaaabaaacdaaaxxabbxaxbaaaabbbdadabaacdacbaxxxbcacdbaaaaaaaacaadabbxdxbxdbxcxdxxbbaaaxdbxcdbaccbcdabbadbdabbadbbabdabbbbadbdadacdxxadbabcdbbaadabbccdbaabaaadaaaaabcbadbdadacacccdbadaadbcbxcacxaaxabxaxdxaacxadadbcxcxxbxaabaaxaxxxaaxbxccxxxbbxabbadxxabxcaxbxxcxaaabbxaxaxxbadxxcaxxaxxxbaxabxddaaaadbadadbdxdacxaxxxbaaaaaaaaadaaacdadabdbaaadxxxxxxaadxacxxaxaxacbbaaadbabdbdbcdaacbdxdbxbxaddbbacbddadacacdbabdxaaadacbaacacdacdbaaxdbxxdbxxxacaaxxxxbbaaacbbacaaacccbabdaacccxxxcaaxacabaddbdaadbdbbccbadaacdaccbbadaabadadadbdbbbdabbbabadbbacbacaaabcxaxxxaadbxaaxbabacdaabbccdbbbabadabbaddbdaccdbdbaxadbdadbabbacdadabdacdbdaxxxxdaxaxcbxdbxaxbaxacdacbxxxaxxxaaxaxaxxddaxdbxaadxbaacddaxaxxdxdxdxxbxxxbxbxcxdbxxbdbaxabbxcxaxxaxbxabxaxbacxbcbacbxabxbcbxxcxcdaxdxdxxxxdxxxcbbdaxxxdaacaababaaccaacbbaaaadbxbdxxxxxxacbaxdbdadxcdxxxdaxdxaxxbababxccdadadxxddbdxxxxdaxxbxxbxxxdbadbdxadbaaaaadbaacdabddbxxbxbbxxbdaaaccdaadbaaabcaacxaxxdaxbaabaxxxbaadbdacbcbaaaabacbbddadaaacdbbxdxdaacxxaxbadbdaacbdbbabdacdaacxxadaxdxabdacdabdadbcaacbdbacbxdxxadbaaadababdaadaddbdddbabdbcbcbdadbbddbadabacbaadbbbababbaddbxxxaaacdadaxcxbxcxbxxxaxaaxcxdxcxdbdxdbdaxcxddaacacdaadxxdbdadbaabdbddabaaadbacbdbbcaaabdaxbxaxxdxbxdxaxxabaadbbbdaacdaaaacabbacaxdxdaxadxcaxaabaxdaaxxacdaaadxxbababaadacddbbaabdacadabacbdaaxacxdxacxdxabxcxbaxaxxxaacbdbcbacbcaacacbabbdbdbbbxcddabaadaabadbdbacdacdacabaaabxdxaxadaxdaxcdbxdxabaabbxaaxxaxbxdbcxbbaxaaxadxbdaaaaaaaadabdabaababxdxxdxxdaaabaccacbdaaaadbaaaaabaaxaacdbadacdbbacbcdbdacbaabcbdbdbdbacbdbddaxababaabacabacaadaabdaaccbdbabaxxxxxxabxabaaxdxaacbdbbaaaaxxxdaxxdaaadxdaaxxbxdxdaxdaababdbddbdbcabaadbaxaxxxcbxxaabxbcdaaaaccaaaaaadbdabxbxdbxxbxxaxdxbxbxacdbxbababbdaacabdadaaaaxbaxdbdxaaxbxxaxdbbaaxddababaaaxbdbxaaaaaxxxbxcxacacdbaaaaabbacacbdbabddbbadabdbxxxxxaacxabxdadbbaddaaadbaddbcdacbcdabbcacdbabaxaxccbbxxbxbaxxdxabbadbaacdacabbbdbabaacadaacdbbacabcacbbdbaxaxxddxxaxddxdbdbdabdabbdddbadaabaaaabbbaadbbaadadaabxabxxdadacbaaaaaaaadbdacaabaxxadbaaaabadbdadbdaaacbdbadbdabadbdadbbaacdabdbcacdbbaacdaaadadacaaabxxaabaxdadbadaaabdbbdadaddadabaacxxxxxxxcbxxabdxdbbxxxxaaaacdaacabcbaadaabacaaacbxxaxaxaabcbabdaabacdabacbacdxdbaabaababdbddaadbaaaaacdbacbabcbacadxxxxxxdaadaadbcbdbdbdaddbabxxaacadbdbbbabbcbdaaacxxaaaxxdxabcdxxababadacbdacadadbbbdbcbbadadadaaaccaadbacbdadaaabadaacacabdaaaadadaabadbbdaaaabbaabbdacbdbbbxaxxbddaaxcbdbxaxxcbdabadaxabxxxxdabbxadadaacacadbabacdbdbadaadaaxxadadaacbadbbabdbdadaacadxcdbxdxcaadbaabbdbdaaaadbdaabccxxxdxadaxbxxdaxdbdbaaaaadbdacbdbbbdbdaabxaaaxabcxadacbbaxdbbaacbababcbdacdbdaabbdabbaacdaacaadbdxbaxxdaaxxdbabdadbbcdbdaaaacdaaaadaaababdbadaxbdbxxdadbaaabcddbabdacabdbaaaadadbbadbbdabadaaabdaaaxdxcbbdbxxaaabxaxxadxxdxdxbcbdaadbabbbbbbdbdbaacdbdadbxdaaaaaaacaabbdbbbdbaxbdbbxbdbxxdbxxxaxxaacbaaaacaaaacaaxxxxabdxbddxaacadbxacxxacxdbaacaadaaaadaaadaccaxxxaacaabdabaaadadacaadbadbdadacdbdbabbaxaxxaaxaxadbaabdabadaaaaaababbbacdacbbdadbacacaaabcbabcdbdbacdaaadbcadaabdbaadbadbadbadaababdaaxdbxxdaaxxbbdaadaaaccadacbbadbcacbdbdbdxbxdaddbadxcbadxdxxxbxxdbxaaabbdaabdaabbadacdaaacaaaadbdaaadbbaxbbaacbaaxbxaxabaaxxdaaxxbxaxcadxxxcbxabaaxxxbxaaxxcbxadxaaaaxxadaaadxcdaabdbdbcabcdbacdxaaaaaacbadbaaadacddbacaaxaxaacaxxaxxxaxdaxaacxadbdbxxxxxbaaabxxaabbdaxxbxcadxxabaccbaddaaababcbabbaxxxxbaaaxaxabaxcbxaaaddbdbbabcbcdbdbaadaacbbbxdxxaxxdaadaaacdaadbcacdaaaabdbadbaxaxxxxaxbxbbacxdxaacxdaxacdbddabcbacdabdaaaaacacddbacdbdaaaadacaaaxcxaadxaaaxdaacaadadbabbcdadabdabxdxxadxaxacxbcdadbdadadbdbababaacdbaabadbabbxacaxxaacxcxdaaaaxbdbxaaxbxbxxadbxxxdbbabbbbcddaadaaadbbbbdxxxaxxcdxaxabdaaacdadbbbbbdaacbbbaaabxabdaadadbbdaaaaabbdaabbbdaabxacxxaaxbaxxxbacdxxxxxadbbaabadbbbdadaaabbadabacbdbacdaadabacbdbdbdabbdbacxxxbaxaaxbaabdbbbbabcaabbdaaaaadaadbbaddbabbdadbbdbaaabbbaaacbbcxxdadbdbaccbadbbaaaacdbbdcxaxxdxcdxcxxxabaxxcbbcaxbcababbdbcacbdaacaaxdaxaaaxxdxaaaxaxaaaccdaacaddaaacddbdddaxxxbxabxaxxbcbbdbbabcbbdbbbdacddaaadaadadaadbbcdacbddbaaabdbaadaacbdaaxcddxcxbbxbcacaaabaaaaaaxxxaaadbaxxadadaacbbaabacdabacdabbdaxbaxxbddxxxbbbbxbxcbxxxaxxxabdbaaaadabcbabaabacbadxdaaxbdxcadabcdbacaabdabdabbbdadaaaaxbbadaxdxxaaaabadaaabxabdbaccbdbaacdaadbdxbaxbcdbaaabbdaadaacddaadadbxbxdabxbcxcbxbxadbdbcbaaaadacaaaaacbdbacabacaccbbaacdadbdacbbbxbddbxaxxbdxbdacxdbaxxaxacbbacxxabdbcxbaacxaxxaxdaabbbbbacdbabacbacbacxaxxxbxadaxxxabaadaxadxadbaxabaaxabbdxdxxcdbxxxadbxxxxcxaadxaacxdbadaddxxadxbaabbaaaaacaaadbbddddaacddadabadaaaaaadbdbbbabdxdabacdaaaacbbddbbbdbaabxxaxbxaxcaaxcxxaxcbxcbxxaadbabbdbdaaadbabacdabdxcbaacxadxaxxxacbaxdxabbbabaabaaadabbcbbxaddxaxbdaaccbacacaacadbddbdaxbabxxaacbbabbbaaxxxaxxcaaxbxaaabxdbbadddbbadaabcbaacdacddaadaxdabdaaxxxxxbdxaaaaxdacxxdaaaaaaabdbaadaacbbbaadbadadacbacbdbabcdbaaadadabxxxbcxdddbbxadxxxaxabxcdxdxxxdadaaaaabaaabadaaaabdadadaacabccaaaaaadxxbaxcabaaabdacbbaabbbdadaaaabacacdbdaaddbxaaaaacaaacaaacdbabaaadbacaaabdadbaddaacdbdbadaabddaabaaadbabbaaaadbbdacddbacaaacdaacxadadaaadabdbacadbabaaxadacdbdbbadbcddabadabddacdbxxbdbdbdaaaadacdadabdabaabacxdacxbacbxxaxdabdaxacxbaacaaaabbaacaacaabadddaabacdbdaadaadxxxaaaacxadbabaaaxxxxcbdxcaxbxaabdxaxaacxacabxaacxxxxxbabxxababxdxbxadxcaxxbxxcbxxxxaabdxadbxaaaaxabdxaxbdaaxxxxxcxdxacacdbaadbbadbbbbdbxxaaxcxxaaaaccbabbbabdaacacdadbbaaddaadbaacxxxacbaxdadbadabadaaabaaabdxaxxaadxdxaaxbadaaaabdbabcbaccaxxbdxdabcaaxxabbxbaxdbxxdbcdbaadacdxxxaaxxdaaadacdbadadbaaadadaaacaaaddadacaaaabdaaadbdaaacxxaaxxabdxacxdbbxaaxxcbxbbaxdbxxbxaacxxxbdbxxxbdaaxxacxaacxacbaaaaabxxbaxacxxcdbabxdbxacxaxdxaxxabcxxaxdaxbbacxdxxbxaxxxbdacbbxddabbbdbaadadaaabacdadbccdbbadadabdacaabbdababaaaaaccabcdbdxdbxaxaxbaaabacxxaaxbdxxdddaaaaabaaacbbcxxdacbbbaddabcdbdabadbaadxxabcxaadadbaaxcxxacbxxaacbddabaaaabadaccdaacdaacdaadbaddadbabcdbbbdadbacbacdbcbaabadaaaadaaadbabdxaxxxxxxdbddaxcdaaabaabbaabdbdabbdaacdaxbaaxxacaxdxxxddaaddxdbacbbxbaadaaaxxcdxxabxxxxaccaabxaxaaxaxaabdabadacaccabbaaccacxbdbcdbxbaxbddxcaxcdaaacxdbdbxxxaxcxbxxxabaxcxabadaabadadabcbaabdbbadbdabaacaxxxaxbdxcaadacaabcacbdbdacdaaxadbcbcaxaxbdaxacbxbxaxdaadacdbadbbcbabdaaxxxaxxxdxxadbdbbxbdbaabdbdbcbcdabaaaadaaadbdaaxaxcaxadbaxdxcdaxxaaaaxcbxaaxcxaadxaaaxxxxacxxxaxcxbxacbcbdabaadbbabdaaaadbbaadadxaaxxxxxbxbcxxxaxbbcxaaxxxxxxbaacbadaacacxdbxaadxcxbaxxbdxxaxaabxaxxdbxxxcadadaaaadbacbacdacddbababxdaaxxaxabxxdadbdxxdaaaacxbbdbaadabababaaacdabddabaacacadbbdbaacaadababdaxxxbxxdbabdaaccbdaababaadaaxadbbdxccaaaaadbdaaadabdaadaaaacdbcdaaadbdaadbaacabacdxxabaaaxbdaabbabdacadbdabbdbabcbcabaccbcabacdadabbdaacaacdaaabdxdxdbaadxabxxaaaxdxdaaaxaxbdbxadabaxbxbcdaabxxaaddxcxaxxbxbaxadbxadxaxbaabadbaxbdaxdxaacdacdacdacbabcdaacdbbabaacccaxxaxaxbaxxxbdxxbdxabxxaaxxxxxbdxaaxbdbxxcaadaaaacaacdbcbacdbdadxxbaaaxxxcxxxcxbbbxxabxxaaxdxaxccdbbbacdddadaddbdabdacdaxacadaaabbcbabdabaabbabxabxxaxcabbaxxcxxxdxdxaadbxaxdbbxbdxxcaxxbcbbbxaxdadaadabbbbdababdaacbbxbdxdacxaxcxabdbxxaxxxxaaxbbaxadbxxxbxxacbbabxbxdxaaxadxabxxbcaaacddbcdadbbdbaaaabcxaaxcxacdbababadaabbddbbdbxdbaacbbdbadabdbaabdbdbaaxdxxabxaaxdxxcaxdxxdadbxxdxxaaabdabdaabaabdaddacbdbdadacxadaxxdxaaxaxbbxbcacbddacaacdbacdaadacaaaababbdbcbacacdaaxxbxxaxbcbbdabbdbdadacdabcaxabbadabcbadbacbddacdbddacadabxbdxbdbaaxaxxaaaaxxxxxabxaabdbxabaxbdbbaxbxxbxxaabbdxxdaxxdxabccxxxxadadabcdacdaaaabbadaaabcdaxcxxabbaaaacbaacdaabadaddbaaabaabaaddbbaddbcbaaaxaadadbaabadbadbdaaabaaacdbbacdabdbabaaadaxbxxbbxcxacbxxdxxcbadaadbcaacddbaadaaabaabdaaabdbaaaaadaaacadbdacbdbacxxxbaxabxaxxbaxdxdaxbbxbbxbdaabddacbcacbaaaadaxxdabccdxcdbabdxxdaabaaacaaadbcbdabcabdabcbdadbdbdacbdaabdbaabaabaacbcbdadabbbdbaaadbdacdaabbcbaxcaacdbdabbcdbacbaabadaacdabbaxxxxxaadxaaaxxbbdaaabcccddbdxcxaaxadbbcdbdbccbdbbabcddabcbdbabbbbadbcadabadaaacaaxxdbxadbxaxabxdxbxxxcxccdaacaaabdxdaaxaxdaxxadaxdbxbxaxadaaacaaccabcbcbacdabdacbacbacdacbacbbddaaaaxdaabbbabdacddabddaabdcbdabdaacbdaacacbaxadadbaadbaaacacaadaddacaaaaacxbdaacxbxdaxaxbxaxcdacbaccdaadadbacdbcbbadacacdabdbdadaacabadbdadaadaccbdbdaaaxadxxbxxbdxxdxdaaacabcbdadacacdabaadaaacxabdbxbaxbxaxcxxbabcxcbaxbdxxaaxaxbadabcxxdaadbaabbababdbcaacbaaaaaabcbcdbbxdxxbdaxcxxaxaxaaxxxxxcxddxxbxxacaxaxaxxxxbcxacbaddadbbdbcbadadaabaababadbaxcdxaaaacaccbadaadbaaacbaaaddbbaaaaacacxcxdbxddbdaxbxxxxxaxxbabdbdbaabdaacbbbabaaaaxdxacbdbadbadbbadaaaaaacddbbxaabaaadaaaaaadaaacbcddbcdaxbaxaaadacaaacdbdaadaacdbadabaaacbdaxabxxabxabaaaxdaadxdxaccadbxaxaxxcxcxadxccdbbdbabadbdaacacbabbaacaabdaacbbbaaccdabbdadbxbaaadbcbdbdaabddabdbbabaabxbacdbbdbxdaaacaaadaaadaacaaaxadxabcbdbdbdadababdacddbaddaaaaddaabaacbdaadbabaxdacbbxadxxabxaxdbxadaxadbaabaddbbbabbbdbxxbabacacabdaadaddadbacdbbdbddbaxadxaxxadxdxxadbbdbaaxaxaxdaxbaaxxaxaxbxxadxdxdbaxxxadabadabdaabbaaabbcdbdxabxxxdaadaxaxadbdbaxxaacxbxaadbaaabaadabdadbdbaacaadbdaadbdabbdadadbaadbabdabbbbcxxcbacbxaxdxdxxxacbxaxcxxxacxadxxdbxdxxxxdxdabdbbadbcxdxaxxadaxaxbcbxbdaxaabbabdbadxxxdbdadxxadaxabxcxxaxaadxdabdbxadxaadbxxabcxxxbxxxacxbdadbdabdbbaaadbdaaadacbaabbcacdababaaaaaaadabdbabaaaaaaxxbxxxbxxbacxaxbadxxaabaxabxaadxxxacxxacdxdxxcxdaxbxbxbaccbxaxdxaaxcbdbbacdaadaadacaddbdbadbbaadaacdbabacbaadbdbaaccdbacaddbbdadadaacdbaaadbcabbbacdbabadbbaaaabadaacaaaaaaaaaaabcaaaaxcxxbxxaacccadaaadaaaaabdddadabacaaabdbadabbddxbaaabdacbaacacacbadbabbdbbaabbacabbaacdbcxxxadxxxdbxxdadbdaabbadaadababbddbbacbdaaxdadbxdxxaaxxdbdaxxddxxbabxbddbadbdacbdbbaabaadaadaxaxxxbxaadxaxxdxabxxaxxacacdabdbxxcbdbabdbabaaacbacxdbxadbxxdbxadaaaccxxxadadbdxacxxxaadabaaxxaxcxbxxxaxbxaxbxabdxxxabdbbdxxadxdaaxcabaabaaddabbaccaadabdbaabbacbacaacbbbddacbbxbadxbbbxdaxbbxxxxxxadbbdbxbxxxbaadbabcadbdabdacabdaaaadbabaabccbaaabadbabbdaabxbaxabxbxbxxaadbxaadacadbdabdbabdaabbdacdaxxbaxaaxdadacbabbdabdbaadbdbbdacaababadadbacdbdbddbbbbbbxxxbaadxaaaxdxcbxadxxaacaaabbdbaacdbdbadaadabbccabdacaddbxaxxbxxbdxdabbaaxxcxaaaadacaaddbaaaabdaaaaxaxxbxaxxadaxbaxbxdbdadabddaccdbbabacbaadbadabacbadaaxxacaxaaxbdxdacaxxdxaaxbxbdadaaxddbaxcacdaxxdacaaaaaccabdabbdbdababxxbacadbdbacadbddaaccaaaaacdadadbbaabcaaxdbxcbxbxabxbaaccbbacbbaacbbcbdbaadbxbbcdabdbadbdbbdadabadbacaxbacdaxcaxxxxxxababxaxdbxbxbxxxabxxxxxacaaaaxdaabaacbaacaaacdbdabacddaaabcbdaaacbaxxxxdxbdadxacxcxcaxxbdabxxbbabaaxxxxbxxacbdadaabxbxxbdaacxbxaxxbcacxxdbxxdaxxadxdaxxbccbxaxxabdbxaabdaxbadacdaaddbacbaabaddaaaaaaadbcbbabcabdacacbcbbabaadbaaacabbbbacbaabcbddbadababdbbxxxxbdxbbxxbbxxdaxxcadaxdaxaabaddbaccbadadacaabaadxaxaxxdddbdacccadaaacbabcdbaacdaccdbdaaaaaacaxcxbadacbdabaaccdbdaacbdaaadbxxxbabxxabbacxbxbxaaaabbcxxdbcdaxbxcabxaxbxcaaccaaaabacdadabacdacbdbxxaxcaaaxccddabadbaaaaadxbcbbabddaddaaaabaadbxxxxxaxdxxdbdaaadbddbdaaabdaaacbabaxxxxdbaxadxxxadxaaxaadxbacdbadxxabbdaxdxabxaxxdabxxxbaxbxxxdaaxbdbdxxaaxaxxadabcbdaaxdbxxacdbxcaadaabbdbbdaccacdadadbaxxbcbdacdaacbcbdbbadxaadbaddbbdaadaadaaacdaaaaaaaaadbbbabbabxaaxbabababdabdbddadabcdbxxxxaxxcxxdbdxdbxaaxdacacxxxdxxxxaxaacbbaxcdbxacbxbdaxdxbxaaaadaddacdbbacdabdabaaaxcxxadaaacbaxxcdxxaaaaccbdadadaaaaaaadaadxcaaaaacdadbdacxxxdbaxxaxdaxxxaaxaaacaxxbdbxcacxdxcbxdxaaaaaxbxaxxdxxxdaxbbaabacaadbdbaaabdbdbbbdacaddbdxxaxxxxxxaabbcbdadaabbbabddbacadbaddxxacbacddaccbbdadbbcddaababdaacdaacbdadbdbdbdbdbbdaadbxxbdxxadaaxcxxxaaxxxaxbdxaxacbxbaxxbcxaadxadbdaabdbxaxbxxxaxdaadbxaxxbxxbxaaaxcaabdaaaaacbdbacdaaaabdbdacbabbbaabccxcaxxxxxxxbaaadxbbbacxaabaaacdbcacbaaacdadaabacddxxcdxacaxaxxaacaaaaaacdabddabdadadaaaxdaxdaacdaaxbaxbaxcxxaxdxbbxxxbdaxbaxbxbaaxxxbdbbdbadxbadxacbabbdadabbaabaabacaaacdbdbaabaadaadaacdbbaacaxbxaxxaxxxxccaacxxbcxxcxaaaaxxddxbbxxcxdxcxadaacxaaxxxxxxxddxaaacaaacbdababadadaadbcccbbbabdbdbacbcbdadbacdbcbcacbacxbbaxxxaacbxxxxbxcaadabbabaababbxabxaaabacbadababbaaaadaabbabadaacabdbddbbabaacaaaadbdaaacadbaababdabdxaxbxbbaxxadxbxxxbcxbababdaddbdacacababaaaaaaaxaxdabbacxxxxxaaxxbbabadbxbdabdbacacdbcbdbacadbcdbdacdaaabdabdacdaacaaaacaaxbxbxxxaxcxaxbaxaacbxdxaxbabbaccaaaaaaaacabaaaacaxacxxxxxaxddaxbdadbxxbxaaxxbdbdadbbbaabbbdaaccaabdaacxxbxxaaxxaaadadbbdbbdbbdadbdbaxdxadxxbaadaaabbcaaaacaaabbbccadadacadbabbdbdbcdadacxdaaxabbxbxbacacadadbdbbadadbcbcdaabdaxaxacxbxaxxbbccbcddacaacdabbadbabcbdacbdbdbabcddadbdacdaaabbacdxxabdbxxdxxxadxxdbabxxcaaababbaaaacbaacdbdadbddbdacdbadaabdbaacdaadaabdaccaadbaadadababadabbcaacdbdddaaaaadbcaaaxabbxbcbacxcdxaabxxxxxcadxxcaaaabacdbacdbaabadaacdaaaacdbcdbddbxdbxxcbxxxaaaabaacbbdadabccbaaaacbdbxdxxxdbcdaaccdaaacbaaaaadadabbabaacbbdadabbbabadaacdxbbaaabddbccaaaaaacdbxbbcdbdbacdaabccabbdxadxaaaxxaccxaxdaaacdaabaadbdaxdbadbbaxxxxbxxxacxxacdaabacdaacabbacbdaaacadaadbddabdadxdxxadbbdaaxxaxxxbbdaaaaaccdadaddaabaxbbxdabxxxdbdaxxxdaabaadbacbabbaabaaaadacaaxxaaaaabccbxbbxxbadabadacbaacabbbcadbaacbdaaadacadaadbadaaacaaaaadbdbdbadbddaabcdbdacbbdaaadadbaadacadadbdbaabdbaabbabdbacbdabddxxxdxabbxbaxddaxbadaadaxbxbaaxbxxxbaaabacaaacbcdbaacdacadbdbbdabaaacdacaabdabcbxbaaxaxxxdaxaxadxbaaaacacbaabcaaadaabaaaddaaxxacbbabxdadaaadaaaabbaadaadbcxxxbdabaxxdbxbaaxxabacadbbababcbaacadaaadbdacbadbcdaacaxxaaacdbbacdabdbbaabdaaabdaaadxbdacxbxdbdaxbxxaxabbbccddbdbbccabaxxdxbbdacabdbaadbddbbabadxxxaxaaaaxxcdxdbacxccaadaxxxxbddbaxbbadbbaabadaaxcbxcxxacaabbacabaddaaacbccdbbdbbaaabdbdacbbcdbdbaaaaaaabacaxbcxadbadacbdacabcdacddaaaaddadxcdaxxcdbxxcxbaaaabcdabcdbaaaadaabbaadaxbxbcxaxbadbabdbaxaxdxbxxabaacxbxxxaxabxcxxdxaxcabdbbdxaaxxxbaxaaxdxaxxxbcxbxxaaaadbacbcaccdaacadbacaabxxaabbcxadxxxdbxbxxcxcxbxddaxxacabcbbdacbbadabdbxxadaxxdaxxdaxxxbbxbaccacxbdaaxaaabdbaacadaaadaacdbbbabababbbaadbcaacxadxaddbaacbabccbdaadabcccaacxbxbxxdxxadaaxxaaadaabaabdbabdacdbadbdacxcaaxdaaxxcbxdabaxcdxxbbxaaadaxdxaxdxxdbbddbacdbbaacaadaacabcdbdbdadbdadbacdbcdxxxxcbbdaacbdadbaabdaaadbacdaaaaadaadadabdbbacddbdabdabcbxdxadaacdacdabdbdadacadbccaabadaadbdabbdxbxxacdabdaacbdabaddaacbaadbbcacbdadaaadabdaacdacadddacdaaadbacbaaaadacaaadacbbbbaccdbaaadbbcbbabxadbacbdxxxadaadaaacbacabaadaadadadaxabbdadbcdbaaacdbbcdaabdbdaaaaabaaadadaacbdbdbcbabdbacaaxbadaaxdaabdbxabbxabxxbaaaxcxxxxbbaxcxaxaxxxbadaabdbbbadbdbaaaaadacdbaadaxxbxcbxdbcdxxadaxxaxxacxaxbaacxaddbdbdbdabdabdbbacabdbbbaddacaadaaadabdaabdbaadacbbdabdaddbdbaacabdabcddbdbcdaabdxdxxcaxabbdbcadbadbcdacadaacbcdbdbbdaabadbdaddbdaaxxacxxxdxxdbaxcxxxxcddxdbxcdbxaxxxdaxbxaabdbacddbdadbbadadbabbdaadadabcdadacccdaaacadbabaaacbacbaabdaadadadbcdabaacdabaaaaxxaaxxaxxabaacxxdxdabdxdaaacacdabaadbdabdaacbcbcdaaaaaadbbdbddacdbaaacdacaaaababaababbxxaxadabdxbdbdxaxabbbdxaxbbxxaadaabacbbdbdbddbcadbbxbbacbdbabxaxxbaxxxdbdadxcbxaxaxxaxbcdxcxxdbaxaxxxaxaxcaadaxbbbbbbabdacdaaaadabaaaabxcxbxdxacxxxxaaxcbxxxdbcbbdbabadadadaaddabdacabcadbaadbadbaaaacaxdbacaabcxaxxbxcaxdbdbbdbbdacabdacbdaaxaxacxxcaxbxxxacacdbcbadbadabbdadaadbaadadabcdbcdbbdbaaxcdbadaaadabdbbdaacdaaabdadxcxabxaabbdbdadbdaabaaacbaacdbdbcaabdbaaacabbaxbadxadxdxxacdaabdbabaadbdabdcddbaaxaaxbdbdaxbxbxbdadbcdadbaaadbaadbbaaaaabdacdaabxxaadbbbcadxxdbdxxdxxaacadbdaacaacbdaadbdacxxxxdxdaxaxadbxbadxbbxxxcdaaxxaaaaaacddaadadbdbaaacdbaxxcaxaxacxxabxbxdbbbcxaxxxacxaxbbaacdaaacabbbdadabcbbcdbxadxdxxadbdxbcxxbxxxaxaxbdxbxxxaxxxdxbbbddaabdacacbaaacddadxbabdxaaaaacdabaaadbddadbaaaaaacbacdbdabaaccbacdabbadadbbadaadbdaadaadaaacdxcxxxxaxxcxbdxxbdxxbxbbxdxbxxxxxaxxcbaaaabcabbxxxxacxabxaxaaxcxabdbdabxdxcxccaaccbxxbacbabababxbaccxaadxbxxxxxxbabxbbccxabdadaaaaadbxcacxxxxxbdbdbaccbadxxaxaaxdxxxadbdacxxbxxdabdadxbacdbaabaaaacaacbdaaaaxabaadbdbdbacdacbbbcaabdaaabbdacaaabbadbddbdbaacaabxbcdbdxdbxaaxxbbxbxbdaxbbbxaaxcaadabacbcacbdabbdaaaaccbxacdaddbdaacdbcdbaaabdbaxcxacbxadxxxdbdxxaacbxxaaacbbabbdbdaacadbdbabcbaadxcxxxaaaxxbadbacbacadacbbabdaaabbbdaabbabdbadaacbbbdbcxxcbxxdxccbxabxaxbacddxxccaaaaacxbabxxdbaadaaaacdaabaaaabdbbabcddabadacaaacabaddadaaacbaacdbdbbcbbdacxdbdbbdbcaaadaaaababdaabdabdaacbdbdbadbadbdaacbdadabacabddaacadbdaadbdaadaddaaacabdbbacbcdxaxbaxxxxxacdabaccbddddbdbdaaacdaaaaxxxxdbxabdaxxaaaaxbaxdbabddbxadaaaxxdaxxxaxxadaxabxaxxbdxcdaxxadxaxaaaxaxdaxdbdxaxbxbxxaaaaaadaaxdxcbxaxxdbbbdbdacdbdaaaacdabbxbbxxaadaxxdaxxacaxxxdbabbaadacdbabbdbacbaxaxdbdbacbabcaaadaaadaadabcaaaaaaadaadbdbcdbdbcabadadaadadbdbacaaacbadaacbccdbbbdaxxabcdaabdabcbdaacabaaxaxxcaccdaaaaaaccabbaadxaxbxdacbdxxdbaxcxxadbdbcdaadbbbdacbdacdacdbacbdbbcdbbabdbdacaabdaabxaxdbxxxdxxaaacdacbacaacaaadbdbbaacaacbbcdbaaaaaaxaaxaaxxxxbxbxbbdbdbdbdbaaacaaabaaaadacabdadacbccxxbcdbxaxbabxxxaaaaxxbaxxaaxabxxxbbxxddabdabaaaadabaadadaaaxdaxbxxaxxddxddxxbcxxxcxacaxdbdbdaaxxaxcxcxdbxbdacbdbdbddaabdaabaacbaadbaaaxabxxabdxdbabbaaccdbaaababdaabdaadadbbdabdxaacxxdaaaxxbxxbaxaaxbacxxaxdaxxaaaacbdabddabcbbbdaaxdxbdxbbxxxadabaxxaxaacacacdadaaaacbdbaadadaaaabbacdaacccbdbdbbbbdaacabbdababbccdaabbxxxxxbxaxbdddbadbbdbacdadaadacbabdbdabaacaacdabcacdbbxaacxadbcccabbbadbdbaadaabaadaxaxdxbbaxcbacbbcxaaxdadxacbacaababdabbddabbabaxdabacxxabaaacaddbbdadaaacdbadxbdaxaaaxcbaacxxaxxdxdxxdbaaddxxbaabadxdxaxdaabacbbbabcddabbaadabdbdbabdbaabaacadadaabdbbadbdbaddadbbbxxadbaadxxadbbbabbbabbdbdbaaaxadbbxdacxaxxxdbxxdbaxabadaacaaddbbdbbdbdbaxacaadbacbadbbcadacaacdaaaabdabcabaaaadaaacabaaabaaabaaaccdaabdxxxxabxbxcxddxaddaaadddaacaaaaaxbabxxccxdaxaaacccbdbaaccbdbacbbcdxdaadababdaaabaadbbbaaabaadbddaabdabdaabaaddacdacadaaxbbcxxxacxacdaxbxcdadbadbbxxbbxxdbaxxbxxbaacbdxcdbxcxbaadacaadbdaaaacacacadxadxaaaaacadxxaxbcaxbacxbaddxxcxbbaacabaccdabadacbbdbabdaaxbbxxxaababaaddadbabababdacbaaddbbdaxxxdbcdbabdbacaaaaabdadaxcxaaxcaaabxxbbaxxxbabccxxxxxxxxabaxacxxbaaddxbaaxxxdaxacbxxadxaaxxxabbaaaaaaabdadadbdaadaadbdbbdbdbdbbxdxxxxxaxadbdbaabbdacddadbbbbacadxaaxxaaxxadbdaaxxabadbadbdacbabdbcadbdaabaxxcbxbxxxcbaabacaaababacaadacdaaadbacxbxcxaabababbaaabaacbacbbacdaxxdaaaxxadaxadxaxbxdbaaadxdxdbcacxaxaaabcdaacabaabdadabdaaadbdbbbdaxadbxdbabxaaxaxbxabxxxxabbbaaddxxxxabdxdaxxbxdxdacdadaaaabadaabbdaacdadadadabbbbaaaabdaadbcdaaddbdacdbdabbcbdadbaaaaadbcxxdxacdbaaabdbdabaaabaacbbdaaacxbdxbdxbcbaabbbbdaabbadbacdbdadacdbadbacadacabadaaaaxdaaaxbbxxxxaaabdxcdadbdbxxxabbxxcbabddaadbdaadaccabdbaaaacdaacadadbaaaddaddacdababaacdbbaadadxcxbaaxcxxxbxxxcaxxcdbabaaacdacdacacbacbaaaccaaaabadxdbdbbbcdaaaaacadbacbacdbabbdbxaaaxdxaacdaabdadbbabdbdbdbdbabadadbdbdaaacadbabaaacdbdbaaaaaaaaccbbcbdaaacdaaccdddabdabaacdbacbxcxdxxxxxbabddaxxxaxbadacaacdaacbdabaaadbdaacdaabaadacbccabaaacabadabaxabxacdbdbacxaaxdaaabcaadaadaaacabdbdadxaxxxcxaacabaacdbdbdaaaacbdaacdbcacbbdbdbacadaadbbaadaacdxbaacbaadbabacdadaaaaaaacbabbbxxaxxxadaxxxxaxababxbdaabdadbddbaacdaaadacaaadabaaaaacdaaaaaabadbbbaaxxxaaxadxaxaxaxbxcxbdbaxccxbadbxxabxddadadaacdaadadbababaaacaacdxbababcbcdbaaaacacaaaaabxxaaaaxaxaabxbacbbdbdaabaadbabaaaaxdaaxxxaaaadbdbacaaaaadaaacabbdbccaxcaadxxaxxadaadbadbbdbdbdaabbdbaaaxadxaxxbdbdaxxdaaxddbxabadxxdacxxbacadabdbabdaadaadbbbacabbadxbddaacxddbxcxbxdxxxdxxcxcdaxaxxxcxcxaacbaaabaaaababdadacdaaadbbdxaxxxabbacxdbxxxaxxbxabdbxdbbdaadadbacacaadaabadcdxbxaxxdxaaabxaabbabdaacaadacdaacaaabxbxaacbadbdbaababdbbdaacdaxbaxxaabdacbxdxdxxaxdaadxcccacbadxxdaxaxxxxcaxdadxcabdacbxaaaxbbxaxxbxaxaxaxddaacbdadbdabdadbadaabcadbbdaxaxxdxacadxaaxxaaxxdxxxcaaaacdbaacdaacxaaxxxxbxaxdbbdacdaadbbbababbcdbaddddaadacbacbaaxxdxaaxxcaxddxxxabdxdxxbddxabxbabbadaaccacdabbdaacaxxdadxxdxabxaxbdxdaaaaadbaaadbbbdbdbababcdbxdbaxbcddxxxaxdxadbxbaaadbdadbbddbaaccaaadxbacbdxdacxaxdxadbbcxadxxxxxxxcxcbxaabxaacbdbabaacadadbbcbcxaxxxxadxbcdabdaadacdaccddbdaadbdxcbdbdabaacacbaabaaabdxaxxcdbdxbadbddaabbdadbdaabaaaabbaabaacxddxaaxabdaxaaxbxbaddxcaxbdaxdbdadacbaaaabaaaaaadadadbaacdbadaaxxaxxadxabdbabaccxxbccdacbxxdddadbaaadaaadbaacxxxxcadabxxbaxxbbcaxxacdacabadaaaaccbaadbdabbacacbacaxxbxaxbxaaaxxxxxaabbadaaabbdbaadbdaacdbdadbbdacabcacdbcacbdaxbxcbaacdaaaaaaabbbaaxbdxbbxaacdxaxxxxxaaacadadabcaabdbcdaabbacadbaaaacaabacbddaaacabbbdaadbdabbdbdbaccbxxxxaxxcbabdxxaabdabadabcacbbbdbbabdbaaabdadbadaacbddaaabbdbdaxxaxbbdbdbbddaacdbacaccbadbaaadxxxxdbxxadaxxdbcxxcdbdbxcbxacxcxadbxaxxbdbxddaaxbxdaxbxbxxbbacbaxbaabbadbdaabbaabdbacbdaaadaddacbadacadacacbdaabdddbdbcxxxaxaccbxacbaxaabbdbadbdbbcdaddbdaaadaadbbbdaxaaxcaxbaadabbadaaccdbacacdaxxxbxxadaxxxadbdabxbbaaadaadbaaaaaaxcxdbxcbcxxxxxbxaxdxbaacbxxbaxxbaxbxbxdacacxabbacxxxxxbxaxxacabaxxdbaaaacdabdabdbabaabbbadbddacaaaacbabbdaadadaxbdxdxcxaacbxxaxxadbdbdbbdaacbcacbadabcbbcadacdaacabaaadacdaxdxaxxccaxacbxbbxbacaaabaaadaabadbxaaaxddxbdaxaxdaxxcabbaaxxaaxaaxxcxbaxxxaadxaxaxbdbdbaxcaaxxxacdxxbdbxaadaadxcxbxbxdxbcbxxbxaabbdxaaaaxxbxaxbbbxbbxaabdxadxaaccacbadbaaadddbadxbxdaaxbabdbbxxbxxxaaacxabxddaacxbxdbbxxaaaaacbddxdbbxacaaaaxxxxxxaxcacxxxbbaaaabbbadaaaabbbdaaabaacadaadbccdaadacabddadaxdxxbxaxxxxdacxdbbdaabdacbdbaacaadbbdacaabxadbadbdaacdacdaaabaaacbaabaacdabdbbdaccbxcdxaxxaabdbcdbcabdbdaabaacacbxxbdaaacbababaaddaaaadbdbcaabaaadaaaaacbaaadbabacacccbdbcdbxbaaxbxdabdbcdaaadbabcdbdbdbadbddaacdaacacbdabaaaacdbadaabbbcabbbdabbdxxxaxabdxxxxaaadaxdxaabxaabxxbaxdxxxxcxxxaxbccaaxxadxbbcdxbdbbxdacbxbaaabxxdxxcbadaababdabaaabaaaaaacadbbxxxaxadaadadabddadaaaabdaaaabaxaaacacabbbbcdaaacdbaabbbbdacdaacdabcbadbcaabccadaabaxdabbbdabaabdbcdadacaaabdaacbdxxbxadbbxxabaacbaxaxxaxaaacbacbdacacbbdaccdabbxaacacdbaaaabaaaaadadbacaaaabdaacdbxaxxcaxxdxaxdxdxxdbdxxacdaxabaxdaaaabdbacbaddbdacbxxxxaxdaaaaaaabaadbaadaaaadaaacdbaaacaadbdbaaaaaxdaxcxxbdxxbbaaaxacaaadbdbbdadbdaadbbdbaadadbdbbcbaacdadacbaadaaabaabdadaacacbdacddbbcbdbbcabbaabbdbdadbxxxaxbcxxxaxxxxcacbaabacaaaaccdbcdabacccadadaadaabaaabdxxcdxacxxabdbxabdxxabxbbxcbxbbxaaxabxabbbddxxbbxbcaaaadbdacbacaacaccaaaaadacccbaaaabbacdadbdadabcaadbaaacaaabbbcacbadacbdaabdacbadbbbdbbacbbbacbcdbdabaaabddbdbxxadxaxxaxxdxdxxcbaaabbaaabaacbbabadbdbdbacdbbaacbaaccdabxaxxbxxdabbxcxbxxxadxxxbacbaababaaabdadaaccdabadbacbdabaadbbcbbdbaacaacxxcdaaaxaxxdaaabbdbdbbdacbcabdabaddaxdbcbabbcbdbacdabaabbdbbacaaacabcabcaxxxaaxxxaaxdxxxxxcacabaaxaacbaaaacbdbaabaabddacaaaadacddaaadaacccbdddabccaxbaxxxbddxacxaxxaaaaxxaabacabaaccbaccdadaaaabdbdbaadxadbxxbdxxxacaacaxabdxxdxxaabcbabdaxbxcdaxacbacxbdaabcxxxaaabcbadaaaaccdbbdaccaaddaxxxccaacdxbxaabaaaaaaabbbbadabbbdbababcddxxxbxbadacadbaaaaabacbbbddacdbdbaaaadaaaccbxbxdabxbxxaaaaxbaaxbxcxaaaabacdadacabacacaabaaxaxcbxdxabacbbdbdaabbbddbaabcaaaxdxxxxabbaaaadaaadbaadabbadbbbxbxaaddxaxdadaxbdxbdbaxaxcbadadbadbbdaddadbdbbxcxacaaaxaxxbxbbxxxaxadxdxxaacbdxadbdaxbadadxdbxaaadbabdadbcabaadbadaacxxcaaxxxcxxabxxbxxxxbxcbacdaaddaaaaaaacdacccdbdabadaaabaxabxdabaaacxdddbxcxxdabbaaacacdaaaabbbdabbddaacabdbbababbdbaacbbaaadbcbbbdaabaaabbabdaadaxxxbbdbaaxxbaaxxabaaaadababdbacbdaddadxacaaccabbdabbdbaaacdbdaaadaaaxxaxxxdxaxxaaabaxaxcxxaxxbbxbxdbxdabcxxdxbxdaaaxxxdaadddbaacbdacdaaabcaabcdbbbxxacbxxxaaaxdbxdaxabdxaaabbadaacdadababaadadabddadadacbxbxbxbxacxacaadxxxxdadbxaxabxdxaxbadabxxxbaaabdbadaabdbbdaadabacdbadaccxbacbbdaacdadbdaddacadbdaabdxdxxaaxadaaxbacaaadaaadbadbccbadbaabaaaaddadacddbacdadbdadbdacacabdadadabbaddbaacaabdaaaadbdbdxaaxbaxxxbxbbbabcdbabbacaacbdaaabacbaaacbcxadaadadbccbcbbacbbadadadxdabdbxbxxabdaxbxxadbbaxaxccxxcdabdaabbaacdbbdbbaabxxaxbdadbaacbccddaacbdbacadbadaaabdxaxxaxbxaacbxxacxxbxacaxbxxxxadxaxaxdadbaxabdbxxaxxxbxdbbxadxabdxxbbacbaaabacbacdabcbdaaaacbxaadbaabaadbaacdadbabcaddabdacbbbadbacacbadabbaaabbabacdbdaaccabdacbdaaddaacbaaabxxxbabaaadbaacdaaabaaacacdaabcacbccbaccaaabcbbcaxxcaacaxaaxxcbdbbbbbaaaaaabacbcdabbdbccadbdaaadbbaaaaacdbaadbdaacdbadadaaadbdaaabdbdaacaabaacbabdacaxxxxcdxbdxxdxaacdaadxxcbaacbdacadbdbdbaaaaacbbdacaaaacdbabcbbcbdxxxaxbbabbcdbdaaadacdbdbbdacbxabbaadaaaabacddbacbbadbaadabbbdxxbbcxbxdbbdbcbbdbadacdaaabaaaacxdacxxacdadbbabaadbadaacdabbdbdddaacaadabaxcxadacdxbaaccxacbadadbccacbdbadadbccdacbbacbabdaacabadaaabaxcxxxaxcxaxacbbxxaccbcdbddbaadbbdbdacdbdaaaaadabaaabdacbddaabaadaacdaaabdbaxabacxxdbxxxcaxcxxxdxdbbdaxbcxxxcxdbxdacabdabbaaabdbdaabaaadaadbaaabdbaaabdaabbaaabaabbxaadxxxdxaaxcbdaxxxcxaaadaxdxxxbdaxaxxxxdacbdbaaacdabbbdbdaaabacadaaadbbbaadbdadaxacaaccdbbcdbabdacaaadabaaacdaaaxxxbaxxxbaxbaxaxbbxxaxdaxabxbaxxaxbbbxadxdaxdbxxbdaxaxbdaxcbbaxxxxxcbxbdaxxaaxxxaadaxacxbxxbdbbcdbdbdabcadacababbdaaxcdbaxbdabddadaadaadbdbcacaaaaaaaababacacaaabdbdbddxxxaxaaxabadxxabdbdaaabdacdaadbadaaaadaacaadddacaadacaaaaacxdxdbxdxbxaxbxadaabbabacdbddacaaaadaaaadaadbadbcaacbabaaabcbddabadbbaaacbbaxxaxxacxxxdaaddbdbaddacaadbacdacabaxxacxbaaaaxaxcdadxabcxxcbxbdbdbaacacdbdbdbdbcaccacdbaacdbabbacdbaabcbaxacdacabacbdbadbcbddabxxcbxxaadxxdabcdbaacacabaaaaaaaddbadbaaabbdaxdxdxddadbaaxdxadxbadxacxabaxcdxdxxxcxacbdacacdaadbaacbbabbbddbbaabaaaababxxadbxxbxbdabaxbacbxxaxbaxaaxdaxxaxaaddxabababbbaaaaadbdddadadaabcabcdabxdxbaaaacbcdbaaccbbbaacbdaabdxxxxaddxadbbxxxdxbdbdbdaabbdaaabacaccabbaabcdadbdaaacacbaacdabbcbbaaddaaadbadaddaabdbcaddaxcbaaxaaxcdadacacbabdaadaacbcadbcaaxxbxdxcxdbadbbabdaabaaadbcdadbaaxcaaxxcxxaaxaddabacadbdabbdbbacbbadababdabdbddaaaabcaadxxacbxdaxacdbbbcdabadbdbaadbabacbcaadabdabacbbdbdbbxdabxdxccxxxxdbabxbcdxxxxdacxcbaxxxcxxxbaxxaxbdxaaxbxdbxdacbbbdbxxdaxbbdbbbdbbabcdbbbbacaacdacdabdbaaadbdadacbbadaabdabdbacdaabadaacbadadaxaxxaxdxbcbaxxxadaxbdxdbaxxdxxxaxxbaxaaxaccxbbcaadaxabxxaxdbadbddxbdxaxdxcxaadxdbaxxxxabxbaaxxdadaxaaxxxxbdxxbdxxaxdbabcaxxxxdaaacbdbxadxacxbxxdxaxaxaaaaxxbxdaxxxcxcxaabaxabdbaxadxbcdbxcadadxadbbxxbbxxaaccdbbdbcdaaaddaxxxddbxxcadxxaadxcxacxadxxaxdxbxaxxbxdbadxaxxxabxacxababbbbadaaaaaaaadbaacdbbbadabdabdacddacbddaadaxxbaxaxxaadxaxxxxbaabbxdxxcdxbxaxdxxdbaxdaxdbxdaxxabxaaacbaddbaacbacdaddadacbdxaxbxccacdaxaxbaxxdxbadbaxaaxbxaxbacbacbaaaddaacbaabdbaxbdaaxxaxcxadbxbaxxacxbbbaabaaabbaaadadbaacddababaxxcxbadbddxbdbaxdxaaxdxaabbbxaxaxbaxbxddxxaaadaxaaabaxxaxbxbxdbbxbaxaxdbbbxbxaxbaxaadxxxaaddxxbdxbxbcaxcaxacaaxdabacbbaaxdxxbxdabbaaaxbxdxcbaxaaxbabaaaddbdaabcbdbdbaadbdbdaacbabxdabxabxbaccacdaabadbbdabaaacbaabdxaxaxxadaxcbdabacdbxbaadbxdbaxaaaaxbxcxxaxbdaxxxdbaxdbdabaadabdacdaadbbaabcbbxcxdbacxbcbxdxabxxxbbaxxxxaaaxacacabxdxxdxbbxcxacxbxxabxacaaaaxxacdaxabaxxaxdbdabdabcbaacabbcdbxxaabxacxxdxaxxxxdaxxbxabddadbaabacaaabbabcdaacacdadadabcacdaaaaacaxcxadaxxaxcbdaadxxxcxaaaacaabbacdbdbdaddxxdaaxxdaxxxxxddxdxxxaxbaabaaacdbaabcbbddbabxdxbxcxbxaxadaxxaadacdaaaabddacdbbaaaacbdabbdbbcdabdbacbabaccaxxaxxxcadaacaaadaabaaadaababbacdadabxacacabdadaacadaadaaaadbdcxxbxacxxbacacdbaaabbdbdbababdxabadbaxaxdxbaaxaadbabaaabbddbbbadaaaabdbaaaadbadaaadabdbbdadacacaacbaacdaabdaaaacaaacaaacacbbdabdbdaaaaaaxbxabdbacdbabbddbbadxbbadxxxxbaaadbxxcdxbcbxaaxxxccaacadaaaacbcadbcadaacdabadbbddaadbdbdaxbaxacxbccdxbdxcaxxaxdbxdaaadacddabdabdacdadbbdbaacddacbdbxxxbxdxdxxbbxcbabaaxbcabxxaxaxxxaabdbbacddabaddbaacdacdadbaaaabcbabbdadaxdaaaaaccddaabcaaadababdaxxabxacabacdaccaabadbdadbxcbdbabaaabxbxdaaaaxacbxaxxxxbxaxaacaaaaabacdaabdacabacaccbaabccaaacacxaxdacddabbdabbdbdaaadaxdxbddddxbadbdabbaaabadbdadbbdbabdaadacdaaaadadaadaabdbabdbbabaabcaabbcxcadaadbdaxxaxbxdxxbaxdbdbaxxaxaxxdbbacdadaadaaaaadabbbcbaabxbdaabxdaaacbdaaaacbabaaddaaacaxaacxaaaxdaxadacxxdxbadbxaxxbxcdbdabdaxcxbcaxxdbxxxabxdxacaaxxdabdacabdaaaadadbbcbabaaacxdaxcbabaacadaaaaaacadxaxaxxaxbaxxxbabdxxxddxxaxabcbacaxxddaacaaacabaacacbdaxaxaacbdbxxcdddbaaaaaabdadbbxxaadxdaxaxxbxxxaxdxbddbdaaadbadaddaabdbdadaxxaaaabaaaaadaaaaacabaccabcxbxabbabdbcdadadadaadbacdaaaacbaaxxdaaaacbcacabbdddababbdacdbcddbbacdbdbcdbbaadddaaaaabdbbabdabaadabccbacaxxbxdxacxxabdxbxbbdacxxaccxxxxbxbdbdxxcdxbbxxcbacxbbxbdxbacxxxadxxxbddxxxbdabaxbxbbdababcacbabaacdbcdbaaabadaxbcdbacxxdacaxacxdaadaaacbaabacdabdbdaabbdadbbabbdaabbaacbaacdbbccdadaxxaxbdadbbxcxxxbbdbdxdaaxxbbbaaxaxaxaaaaxacxddaxxdbdacaxbxxbxxdbdxbxdbxbxbxdabaxcxbdaxaaxdxaaxdaaxaxdaxxxaxacxdaxxxxdaxcddxaxdaxdaxbxxbdxdxabxxdaaxbcabbbdbaaacdbaaaccbdaaabxcxcabdacaxxxbxbxabxdbaxaaxaaaxacdadabaadbbabdaacadbdaaaaadbdbbbdaxdaadbxxxxddbxbaxxcabdadxbxxaabadxxdxcxxxaaxxbxdbdaacbdaddaccacdaxdxxxdbxacddbcxaadadabaaadabacddbbbbdbaccbcdadadadaabcaaxabdxxdxxxacxdacbdbaaacdxdaaxacaxbcbddbcabdacdacbdaadbdababdbdbaaaxxadbxbaxcaxxabacdbbdbdabdaabaaacdbdbdbbaacdabdbbbabdbdaabxcbxaxcxcxcbbaaadaaaaacabdbdaxxacbabbdbaadaacbbbdadddbdaaacdbacbdbadaadaddbbdaaaadabdddbdaddbaaxddaxbxaaxaaaxdxadxxaxaaxdaxaxabdxaxxdbxbxxxxxadacdaxbaxxxxxbxbdaxdxcbaxxaxbaabxcaxxaxbdabdadabcbadbadaabadaadxbaacbaaxdacbdbxxxxxxxbxdbdadbaaadacdaccbbcdabbaddbacabaadddaaaadbcacxdabaxxxxaaxaxbddacccbbacbbaadadbddabbdacaaabaaabdadbdbdaadbdbaaadbbbbxxacbaaaaadaacbdaaaaacdbccxxxcxxabaxbxdbxxcxacabbbxxabxxcxadaddxaxxxcabaaababbbbdacbadbcdadaaaadaacacacdabaacxdaxaaxxaaxxdaxbxbxxbxcxcxbdaadbcbaadaadaaadbdbbacbbdadaaabdababbdacadaaaaacbcacbaaaadadaaccxxdxxacxxxaxbxaadabbadacdbddbaabbdbbdxxabaxbaacabbdbbccdbdacaaacdabddabadabxxbccbbdbxxxcbdaxxbxxbaaaaxxbxxxadbadbacbdbbadadaaacbdabcbxaxxbaaxdbaxbxbaxxadxxxdaaxdxbbxacdaxxaxxaaaxabxbdxxxaxxcdxabaaxdbxadxxxdxxaxbdaxbbacdxxbbdxdxdaccbcbdbadbacaaaabbbadbbccbbaabaacbbdbdbaaaaxxxaxxaxbxxcadxxabacxxxaxaxbxabacaabadbbdbdbdadabacbaaadadadaxaabxcabbacbdbaaadaadbcdadaaaaxxaxbaxxaadxxbaxxxaadbbxaacxacbdbaxadacbbbacbaabbdaddbaaaaxcxxdxdabcadadacadadbdadbaccxacaaxaxabcdacaacbaacaacacaaacabdbcbdxxadxxdbaddadbacdaaabcaaadaxacxabxcxxcxxdaxbbdxdxcxaaabaxabaabaacbdbddbaaccdbbbdxxdbdcadaacaddaaadabxacbadbaabadabbaacdbaaccddaxxbaxdacbcabdbacabdaadbxxcaxcxdxcxaaxcbbxxacdbxbddxxxcbxaxadabbxdbxaxxabxxxxbdaxxaxaaddbaadbdacdbadbbdbadbabdbaaxaxxbcxbadabdbcabdbbabdddaacbaxxacdaacdbdaaaaaaaadxdxadbdxxabdxxdabaaaxcadaaaxadbaadbbadaadaadbababdaadbdaddabaacdaaacbacbdbbabbxadaabbdbddbabbdbbbdababdaaxbdaadaacbcbacdacadacbxxcxbdaxadxcacddbaaaadbbdababaadaaxxxxdbdbaaaacxbcxabdxddbxxaaxaaxbabxaxbaabaabbdaadbdbdacacddacbdaabaxxacxaaxbbdbxxadbdxaxxbaxaadbxbxdacxxxdbxxaxbxdxbxbxaxcxacbbbbcacadaabacbabcbbdaacdbaadabdbaacdbaxaxabxbaxbaaxbccxxbadxacxaxadbaacxxxxxxaxaaaaaxbdacbcbadadaaccdadbacdacadbaccdaabdaaadaadadabdbacbbdbaadadbaadbaxdadxxxbabbbaxxaxxdxxxbaxxxdadbxaaacxxaaabxdxacdbaadabaaaadaacadbbbacxxdbdbdxdxcdacaxaxaxcxxaxbabcbaadacbabdbaaaaacbabbacbaxaxaxcbcadbaacdddbccdaddababcbbadadabacbdbababaadabaadbdbxbaxxdxbbbxxacdbxxbbdbcdbxxcxaaaxaxxcxdxabaaadacbaacdbdacbddadadbxxdbaxaxbbcbcababdbaacdbbadadadaadacdacbaxbxcdxcbcaaaaabbaacaaaaxaxaaxdaaxxdbaxabaxaxxxdaaaadbaxxxxdxxxxbdbxbxacbbabacbdbaaababacdacbaaxxxbxbadxdacdbxbdbbdbadbbacbabdababcdaacaxxaacdbbxbxxdxaxcabxxxdxaaaaxbacbxxxxxcxaacbbxxxxaadaaaaabdabaaabaaaaaaabacxxxbbdbxadbaaaababcaaadaxaacxacdaabdbxxxxxxdxcdxabbxxadadbbbbcdbdbbadaaxxbdxbdxadxdbadaxdxxdbxaxxxdacxxxccxxxaaxbxbacxdacdaxdaaxxadbaaxbxbxxxxcbxbdxaxbaddaxxdxbbdxxxxbaccaaaaxxacxxxxbaadxbaadbcdbabadaaaabadabbacdbdbdadxxxdbxaaxbddaxaxccaadxcbxxcxadxaadbddaccxbxxxbacdbadacadbaaacdbbabdbbaaabbdacbbxxdxxxbaxaaxbaxcdacdbadxcdabxxxxxxbxxxdxxacadbbcdacaaabaabdbabdbadacbdbddbxabdacadacbdbaaaabdaacbadbacdacdbdacdaaaddxdacbdxxaxxadxbdxdaabaxcxabbcbcdaaacbacdaadddbabcbaaabaaadbacxdbxaxaxcadbcxadbxxcxxcxdbdbabdbbbdacaaaabxccbabxabdabcbbabaadaaaaacbdacabddbbxaxdxdaxxxcddaxxadbxbadbdacbccaaxaxbdxxaaxbxbxcxaababaacbacdbaadaabdbxxbxadbdbbdbbacbaaacdbaaaacdabadabacbacdbcacdbadxdabababcbddbbabadbadbadaadacxdbbabdaxddbaxbbdadaaababdabbbddaabdabaadacxxdxxaxxdaabxxdabxaabxdbxbaxbxadaxaxdaxxxcxaxddbdbxxxdbxxbdadxxxxdbadbbcabaaadbdbabbaabbabdadbbadbaabbcdbdabcbbaacdxxabxxaaabbacbbbbabdbbddbbaxdaxxbxcxbxxxbacbadaxxaxdxxdxdxcdabadababdabdadbdaaccbbbdbaadaaabbcacccaaacbaacdacabadabdbxdbabccdaccadbddbbadxabcdxbdabxdaxadaadxdadxbbdbdxxdxaxdaxxaadxxxxbbxdbdbdxbxaxcxaxaxxxbadaabdxaaxacadbdbcdaaabaaccdaaaacdbdxxbaxcbdadacdacaabdaaaaadbaaabaaaaabacabbaacbcbabxdxxxadbdaacadabbcdaacbdbddbabacaaacbaabaddadbdaxadxxxdabxcbxaaxdaxbadbxxcdxaaxcdbcdbddaaabdadbaddaccdacdaabdacbaabaaabaacadadadaabbbaabxbxxdbdabacxaxaadaxaxaaadbdbdbabcbbdadabxxdxxxbbadaaadaacaaacbacdbcbdbbxbxxaxxxbdbxaabxxbbxaxaadxxbbxaxxxbxbdxaabaxaxdbaxxxadaaaxaaabdbxbadxdaaxbdaabaaacbbbdbaabbabbxxacaxcdxdxxxaxaxxxxaaccbdbdaccadabaabdabdadxadbabaxbdbaaaxdxxacxaxdbxccxxaxaxxcbbabcdbdadbaaacabdbbdbababdabbcdacdaabacbdadbaadaabcaxbbdbxaxddacdaaxaaadbxaaacxxaxxxaxxacaxaddxxxdaabaxbxxacaaaxbxcdxdaaacdaacbcbaaacdbcbbaabaaaccbabadaabaacdacbdacbbdaaadbbaaaaccacdacbcacdbdabcbdabacdaadxaaxxaacacdbaaaabbaadacdbbddxaaddxcxxbxxaaxdxxxdbbbcbaabaabacbdadxbbabaxxadxbxabxxxxdxaaaaxxxxcbxxadbxaaxxdxbadbabxbxxaaaabacaaabddadbdacdaxdaaabbcacbxxdbbbdaxxdxxacacdbxaaxdacxbacdadbdacacabdbabbbaaxdaaxcaababadxaxacxacbabbacacbaddaadbdbaadbadacadaaadxadaxcbxbacbacxxxdxaxcdbbacxdbxaxdxbaaxcdxadxbxdxacxbdacxcxbaxxacadacbaccaabdbbcdadaxdaxaabxxdadxaxbaaacbacccddbaacaabdbcabaaacbdadbcbdadadbdabxccaaxcxdabcxabxxxxaacddbbcdxaxbxadaaxbxxaxbabxddxaaxaxbdbdadbccdabaacacaxadxxxxxbxdxxbadaxxxdbaxaaacxxxxxaabadbaaaabaaaaadbaadbdaadaaaaabbaabbbaabbbdbxaxaxxbdadbxxaxdbxxbaxxacdaxxaaaaccacdbddabaabbdaxxxcaxdbcbbadbcbacabaaacdbbaxaxxbxbxbxbdbadaabbbxccbcbbaddbdbdbcxxbaxbxaaadxdxaccdxddxaxadbaxaadacacxxxxxcdaxxxdabaxxbxcbxxcxbdbaxddadabaabaaacaabdacxcbxxbaadxdadbaabaaaabaaaaxadxxxdxaaxxcxxbdbdbaadabacdabaaabdaccbacbcbabbdadbbbaabaabdbabaaadaccdbaacaaddabdabadaadbcbdaadaabdbdbbdabbaacbdaaaaaddabxbxxdxaaxcxcdxbdxxacbaxaaxbdxabxxaaadaacadbxxxdxxaxxcacxacxbaaxxxxaxabcbxxxxxxbbxbaaabxxdadaaxaaxxaxaabxdabbxxbxaxdxbxacdaxbbxaxabbcbbaacacbdadacdbbdbaabbxxcbdacaaaaaaaaabaacaaaxdxbabbabbaaaccdabdadbbaacdadbaabbbabbdbcaacdadabdbdaadbacdbcaaaaaaaaaaddxxbdxbaabbdbaabdabdbbaabbdabbdbaabaaadbacaaaaxxxcxaxdadabadbdaabcaaaabaacdbdbaacaacadabxdaaadaaaxbbaxxcxxaxdbxdxxxaadaccdbadbadbcdabbdbaaxbxxxacacbcdbxbdacaccbbdabbbbabbccbdbadbacacaaabdaaabbdbcbbbaccaaaaaabacbaaaaadbdadbcbdxbaaxxxxbxadaxxadxacdbdabdabadadadbdbaaabacadadaacbcdaaabacbaaabaabacbdaxdxaacxadbxxbbaaxxcxacabxcaxdxbbaabxbdbxxcxbabxcbdbaaaadbdabddacdaadacdadbabcdabaacddaacabbbxdaxdbcxabaabbdaacaadbdbdaaxxxadbdbbdbacadacddbdxxxxcaadaxxadacaxdaxadabadaacaaadbdaaabadacdaaacxbdbdxxxxabxbadbadabddadbdaabbaxaaacxdbxxadxbxdxxaxbabdabdacdbaaabacbcaaadbadadbadbcbacaaaaaxaxaaxdbbacbdabadacdbddbdadadbdbddabdxdaaxbababxxbaxxxxcaaxxdaxxcxxbxdxdxxxdxxabdaabbdbaabdaaabbdabacaabbdadbaaxaxxbbbabdadaaaaaccbaaadbdacadadxbxaxaxaxdbdxaxadaxdaxcacxxxaxaxacxxxxxcbaxxadxaxdxxxadaxbaxdacbacabbaacadacadacacdabaxxddabbxaxabbbcdbaadadadadaabaacabcdaccdabcbaabacbdbcdaaaxxxxaaaxbbxxxcxbbdbaacdaacbadadbaacbxxccdaaadbbaddaacbbcadacdabaxabadadaadbbacdabdadaabaddbcacbabcdacbbxaaabcaxacdaxxaxbxbxbbaxxxcddxaaxdxbxdbxxcbbaaacabdadbadbacaabcbdababdbdaadabdbaaxadabaxbabcxaxxxdbacxaxdaxdaaadaxbcxxxxxacaabadbbbdbdbdbdbaadbabbcadaaaabdadbdaadbdbcabcdbcbdbaacbcdbdbacdaxdbadacbaxaxxbbxxxaxdxcxxcdxxxadbdaaxaxbacadaaabbaaccccdbaacbcdbdaxxdacbadbcdbbacdbabdabdbadbabxxbaxbaxxdxbxxxbxxxxabaadxxbdxbxxbdxabbcabacbdbaaacbdbdbacxdbbcaaaddaaaaaaabdxcbbaxbbacddaaaaacbbabdaacadababdaaaaabbdaaabaabdacbbcaacxaxbbdxxxxccbaabcbbbaacdadbddabaabdbaaddababacbbbaadabbdbdxdbdaaaxxxbxcdxbaxaxaxadbxbxxdxbaccxdaaacbabddaabcddadaaddadaaaaacaaaccbacbaabaddbdadadbacdbbcdacbxbbxbaxacaaabbbdaacadabcaabccbaxdacxxxxaxxabxaxdbxbcddaaxdbxxxbxbacdaaxacdbddaabaabbdabcxbaabxadxxbdbaabbdbdabacbaddaaacbdbaacaabddbbdabdbbcdbaaabbbaaccdbaabadxaxbxaaxbaxxcxaxdabdbaaxdxxxcdaabdbaabbbdbbdbdaccbaadaccdbcdbacabaacbdaddbaaaaxbdxaxacbadadabbddaaaacccdbbbdbcbbcaabbbadacbadbdadbdaaaadacbacxxxdaxbdbaxacbacxadaaxaxbadxdbcdadbaaxxbxxbxxxxxadxaaabcdxabadadbcdbabdadbaddbabdbbaacddacacdacbbaacddbbabdaaaddbabaabbdbdbaaaabcabbadbbbbbxdbxaddbabdacdbdbacaaaaxxaxcdxxxxdbadadbbxcxxxxaabdbxaaxxaxxxbdxxxdaaxaaaacaaababbaacxbbxbxxxabaabadacbacdbbdaacadbdxdaxxdaxbxaxdxxcaaaaaacadbxaxbdacxadxbdxbxxabxcddaxaxxxcxxxcxaxbbaxdaadxdxaxbdabxxccbaabbbcabdaaaaabdaxxcbbdadbaaxbaxaxaaxxaacdbdbdadbbabaaabbdxaxxxxbxbxxaccaxxxxaxxbxxbcxxbddxcabdxdxcaxxbaxbabbaaaxadxdxcbxxxdxaaxxxabxcxxabxxxaxbdbxbxaxacxxbbcxaxxbacaxbxccbxdxaaxxxaxbxbaxabaxadabxxxdddxxabdxdxdxaxxaadbdaxxbxxxdxxxdbbxbaabxbxxbacbaddaaabdbddacbdabdaacbabddaacdadbacdaaadaccdaacdxbdxdaxaxaxaxxxbdbdaaxxacxbdbdaaaaaddaacbbdaadbdadxacaxbacxdxcxdxxddxbaaxaaxaxbxdbaxacxxaxxbxaxbabxxdabdacbdxaxbaxdxdbxacdbxaaxxbxaxxxbadaaxbaaabxbdbdadbbadaaacdbaaabdadabbbaadacdadbabaacdbdaaaadadaadaadaaadbacadaaaddbaaadaccbcdabdbacddbbacdaaadaaxabxbxxxbaaxbaacdaccaacdbdadabacbbacaaaadaaxdacadbacaaaaacaccacbddbdbdbbdadaabaaacadbddbbbdaabacdbaxbxxdaxaccaxbbdaadadbdacacdbaabbxxdaaadxaacbxaxxaxxcbaadbabcdabcdaaaabcdaabbadbdxxcaxxcdxadbxxxaxxdadxxxabxxxcxabdabdbadadaadaaacadbacccdabaddaaadabcaadbbdbxxaxbdbxacdxxxaxdxxxaaxxdbbdaxxcaxaaaxdxcbbaxcxdbxbxxxaxdbaadaacdacabdabdbdaabacdxcxcaxbacxaaxxxababaxxxxxaabdaacxadbaaabaaaadadaaaxabxaxaabbabbbdxabxddabadbabaaabbcabdbadacbabbbadadbaabdadabbbaaaacbdaacdaacbdbadadadbcbcabdacbddbadbaacaaadbdbbadaacaaabdadbbaacdacaadbbcadaabaadaabbbdacbaxxdxbdaxaxdbxbdbabbdaacccabcddbaaaabdbadbacaabdxbcxxaabadxdbcxxxbxxaxxdxadbdaxxaxaadbaxxxbxcaxxaadxdabcbcacadacadbdbabdbdbbdaaabxbaxadxbxxcdxxxbxaaxbdaxxdbcxaaxxxabaabcdaacbaadbabaadbacadbdbdbcbcaacdbdacdbdaxaxdbbdabxaxbaxdbxdbxdadabxbxdbaxaxxcacbadacacdabbaabcdbbbcdddadbddbcddaaacbccbdbcdadbcbcdaaacdxbdbaaxacxdbxxxxxcxadacbaacadababaabdabdaadbdaxabxaxbxaaaxxxcadaxxbabaaaabdacbbabbbaacdbxxxbadxxcbxxbxxxxxaaxxxbadaacdadaadbbbaaxbcdacaaxcbaaxxacbdaadbdabbacdaabcdaaaaadbcdbcccbdbaaxaxaaxxaaxaxdxdaxbdbxxabaxbxbaxxxbbababxxbxdbaxbdacbdbacxdbxxxxbxxdxbbacdaaabdabadabbbadxadxaxbxcxadaxdadbbacbdbadbdadaadaaaaacbadbdabadadbccabbabadxdxdxcxbdaaaxbdaacdbdaaxcdadbbccacbaaacbaaabacdaxdxaxxdxacxacxxxaxcdaxcaxxxcxxaaaccbdaxxaxaxdadaaddaaabaacaaaaxbaaxaacbacaccbdaaacaaccacbabcddbaadabxxxxdxdxdbadxdaxbxaacxxdbbdxcaxadbxbxxbbxabxbadabacaacadacbcddbcdaacddbabaxxdabdxxabxxbcbdabaaabbdacbdaccbadaaaaacdbdbaabdbaaaadabacbdaaaaadabbacbxxxbxaxabdaxaxaccaxbaxxxxdbbdbbaaaaabbcadbdadabdadbcddbdbbbaabdbaaaxbdxxxdaaaaxxadxxbxxxdxxcaaaaabaacxbxxadbxxacdbdaabdbaabaacadxdacxxxacbdxbxdxxdacacxdaxbcbbdxbadaacaacaaaaabdaacdaadxacddbdacxabbxbacxxxaadaxxadxxaxbxxabaxxxaxxcbxdxxbbxbbxxdbaxbdxaxaxacdbxxdxbbxxaxaxacbdbdbdbbbdbadacdaccabbaaaaaddabbdabadadbccaadaacddbdbbxadxaaxxxaxcxbxaxxxxxcxbdaabaxxxadbxbxcddbaxxxaxxdbxxacbadababadbdbabadacacbaaabxcxxdxxcaxxaxxddbdaacbadaccbcabbbdbcxxxbbxxxbxbxbdbaaabacdbaabbabdaadabdbaaabxxxxaacbcxxacbbaaabbadaadadabadaadacabaabdbaadaaaadbcaacaacaadxdxadbbxacxdaxdaxbaxxxdadaadaaabdaaaacdbdbdacadddxdxxaaaaadbddaaacbbbdabaabcdxaxbdaadbdbbaaadaadaabbbacdbcaccbbaabaacdbxxbaaxbaxxxbxcbbxxxaxxdbxadxbxdxaaxxxdxcbdxxbxxxbxaadbbdxdadbabddabbaadbdbaaccxaaaaxcxbaddababacbadbbaabacdbaxaaaacxxadbdxxxdxxdbdxdxxbaxxxxxxbxdbaabaacacaccaaaaaaacbaccbxabaxxxdxdaxdaxbxxdxxbbaxabxbaxadabcaacaaadbdaacacbdacdadaabadacaaaadbxdbacadacdddbaacdbaaaabadaabaxxaacxaxaaaaaaabcabdbbdbccacdbabadbbxdxxacbadbdbacaxacacdbaaadaadabdbacbabdbxbacxxdaaxxaacaxxxaadbbdbdaabdaaacddbdaabbbbbbacabaccaaadxxxcdxxxaxddxaxbaxxxabcddadbdbbacacddabdbabdabaaxcxxaaxxxbxxaadxabdacdaaabdbbdbdabdacxxxbaaaadaadbbadbadadaacbdaxxbxbdxdadddbdadbdabdacdaadabaaccabaacbdbadacxaxxxbdxxxdacdaacaacddbaacbddbdaaadaxbdaxxxxxxdbdbabaxbxbxxbaaccxbdxaxxaadbabdxxdbbabdaadbbdaddbabaaaabbcbaadaabbbcabaxacbdxaxaabaadaxxaxxxaxxcacdbaabdaadbdaaaaaadbaacbbdbaabacacbdbdbacaaabbaxxbadaadbdbabbadbcdbabbaxaxdacxxxxbbdadabbaaaaadaxacaaacbabxbdxadxdxaxcbdxaxdbccbdxbbdbadxxxxxxccbxadbxxaxdbxcaaaacxxbabadadbxaxxacaccddxaxdbadaaxdaxxxxaxbdxxaacdbcadbbaaddbacabxcbxacxbbbxxaaxxxxdbdabaaacaababaaaabdbdabaaadaaaaaadbaaacbbbxxaaxbbxdbdacaaacaddbaabacadaacbadbdaacbcaadadbaaxaxbxxcadadbbaaacbbdaabadadadbdxcxxxccaacacbcdbaaadbabbdaadbacdxxdadaddbdadaabcaaabbabdabaxdbabxxxxbxxcaxxbadaxxxxdbxaxdabaxaxacbbaxxxxxbxxdbbxabacacacdbabadabaaadbabdbbbabdabbadabxaxxdxxaadacadxxbaaaxbdbxxaxdxdaxxxxaabacbbbbabdbaabdabbaadxbdxddaxxxbdxdbbaaacabadbdadaadbdacaabdaadbdaadxaxcxxdxadxxbbaxxdxcaaabaaaabaaacdadbcadaxbacddaadbacdbacaddbdbacaabdxdbaxxxaadxxddbaacdaaaadbabacaadaaaaabdbadbcadbdababdbacadbdbaaacdaabdadaaaxdacxbaaaxxxaadaxcaxadaxdxbdxaxxabaxbbxdbaaxaaxbdbdaabdbbaaabaacdbcaabdbbaxbdaxbxxxxxxxacxdxdbxdadbcbdacdbdbbccdbxbdxxaxxxaxbxabbabbxbxaxaxaaaxaxbxbaxcabdbaacdbbddadadabadaxxxdaxcadaaaadbdxabcaacdbdbbcaaaacaabbcbddbdddaaacacabadxaxdxbdbbaaccdabdbaaaaabdaxaxxxxbxdxaaxbxbdbbbbaxdaababbabaaaaaacabaaaabababbxaxbxabbacbaadbabbadaaaabbdbxcxbcxxbxadbacbbacxbaaddaxdbbaxxbaxabaxxdxaadaxcxdbdxxbaccbdaaaadbaaaaabdabcbadbadaccaddaadbbadacbbcbbbxxaabcbcxabaxaabxbcadaaaadbadaaaxxabaadbbxaaxxbbxabxxbaxdaadbcbbadbabdabacbaabdacdadbdaadbbbdadacadacdbaadbbdbxxadbbdbcadaabadbdabbcbdabaadbxbbxxbaxxbdaxbxbxbxdbaxbcadbaddacbddbbbdabbdbbdaccddbaaaaacxxxaccbdbdbabdbbbadbaadacaaacbadbcdbaabbdaadxcxxdxxacxaabxxbaadbcdaadbdbabbbdaabadadbadxxbdaxaxacdbacxaxxdabxbdbadxaacaxxcdxdxbxxbxcxcxxxxabdbbbacxxaxxdbaabaddaddadbdbaabdacacxbdaxxxaabxaxxxdadbdacbbbacabdbdaadaabacaaacaabdaxbaxxcdaxxxxcxbxaxdbxxxbxdxbaaaxdaxxdaabacdxdbaxxxdaxxacaccdabdbabdabacaaxcxbdaxxxbxbbacdaadbdaaaadddaacdbdbacabacaaaaccbdbdacdbbaaxbxxxxbacaxdxxxbcxxaaxabbxabaxxbxxbxxbaaaxxxcxbdbdaadacaacadaadaaabaacbacddbddaxacxxxxcxaxxabxbxdxcaxxaaxaxaxxaaxddbaxaxxxxaaxxadaxabcxacbddabdbacabdbbdadbdaccdaadacaaacadbbdaacdbacaaaaadaaxxdxacdacxaabxaaaxddxbxxaacbxaxcdadababbcbcbdbaaacaxdaxdxcxbaadbdbbacdbdbdaacacbxaabaxdaxaxxxddbbbxxaxaxdaxxxaaabadaxxxbaaxxaaadxxxadbdbdbdbdbadacaacdbdaaabdaaadddaxdxxxadbxdbdaabbaaabaaabcdbdbacacbcdaccacbbdaabcabacdabxadbadacdaccbccaadabadbaacdbacaaadaxbdxdadabxadxddxxxddbxxadbdbacxdxdbaabxbdxdaxddaxcxdaacdacadaadaabdabbaaddbaxcbaxxxxdbacdbbbdababcdbbaabbxddxxdxxcxcaxaxxxdxdadbaaaacbabcabdbbabdxxbxdadbxxbbxabcbdaadbaaaacaaaacbaaaabcdacadddacxcxadaaxxcadxxaacaaaxaxcaxbbdaxxaxbdbadbaaddacdbddadaaaadadbaadxaaxaabaxxxabbbxdxaaaababxxxaaadbxadbbxacbxxxxadaxbbcdbdacabdaaaaacdadbdacbaddaaxbxdxxcbdxxaxxbaxabbdxbxdxaxadxxdaaacdbbxxxadxxbbaxxbaxbxacacxxbdxadadaabaacadacabbdbaaabacbabbbbcbdxxaxbxbaaxdxxdxaxxxadxxaddadbcdbabadbdbdadbcaaddbbadadbbaadbdacddaaabbdabdbdbbaaxdacbxcacbaaabbcaaccdacdacaaaacbaddaaabaddbxxaxddaaxxbxadbdbxbaxdxbadbbxxcabaxxbxbxaaxdxxxxaxaadaaxxbcaaaaaxxdxxbdaabxxxccxaxadxxadabaxxaadaxbbaacddbaabcadbaacdaabbdaxdadxaaxxbaadaxxxaxxadbaacadabcbbbaadadbdbcdaaxxbdacabaabcdacabdadbdaacaacdbaaaaaabxxxxbxxbadxdadacbbaacbbdbdbbdbdaabaaabaadbdxdbaaxxcxxcxxxxaaabxacxdabacbbcdabaacbdacbdadaxcaaxxaxbababcacbbbcbbdbaadbaxxacabbadadbaaadaddaabbdadbdbdaadbdbdaaabdbaadabbdbacbcabacdbadbabcbbabcadacdadbdabcacxaadaaaaxabxaxxxxbxdxbxxaadaxdaaxxcxxcaaabxbcacxbxacdbadbacbacxabxbdbxxacxbxaadxdaadxdacacbcdbaabbbbbaacbcaaaadbadbacdabaccbacaaabaacxxaacaaadbaabdbcbaacacbaaadxcxxxxxxadxcdbbdxbdxxbxdbcabcdaaacdacdaaadxxdbxcbxcaxaxxdbdbxxaxbabxxaaaacbdxxxcxaxaaadaaaaabdbdacdacdbabdbaacbdbbabbacbaabacadaabacbaxcxadbbbxaxxaxbaadbxbbbdaadaacacaabcdabaabdbdbdacbcdacbaaccdaabdabdabaacbdadbacdaabdddaacaabcabdbdxxxabdxxbxxacxbxbaacbxxxaxdbxccdxxdxacxbxbbxaxdaaaaxacxabdbdacabaadaxxcbaaxxxccbxcabdabdaadacaadbdaabxabcbaxxbaxxadxbxaacxbxaaabbbxdbbxdxaxxbdaadxxxxxdabaabdbdxadaabdabxdxxdbcbaaaacbaaddaadbdbdbabadxxbxadaaxxacxbaabdxdxdxxadbbadacadabaccbdaadadbabbabacdacaabdbabadacdadabdbabaacbbdaaacdbadacbabaaacbbacdbdbdacdbdabaadaaaabbdbdaddacacbxxaxxxxxaabdaabaaccaaaaaaaacdacaaaaaacadxaxxcxxxxbxxbdabxxxxbbaabdxxbadbaxbacbadbadadababacbadacdbadbdadaabdbbadaadaxdxdadxxxaxdxdbxdaxababaaadaacdaaxdbxddxaaxbbdbbxbaxxxxaacxxaaxadadxbbdabxxxxdabxaxxxbxbaadacadxaxxaaxabbaadbbaxxxdbxxdbxaxdaaaxxcaxdxacabbcdxadaacxxxdbaaaaaxaxaxccbdadbaadadbaadbdbdacbababaxxbabdabaacaabbababbadacadbcacaabccaabbdaaaadaccbacdbdbdacaabdaadbbbdbbabbxbbxabdacdabadaaaadabdaaadadxdacaxadxaaxxabxaxxaxxxacaaaadbccddadaabadbaxabxdbxacbdbbbdaacdaaaaacccdaadabdbadbababacbbdacxxxxdaaabxxxadabxdbxxcaxxxadaxaxbaxxxxxcxaaxbaxdxxcxxcbxbbbdbxxabcbbacbcacadaaacaaabbcaxacdxadabdxxcbaaaaaabaaaacbbddacaacdaaacdxbdbbxxxcaaxxaxadbxaxxbdaabadbdbaaccbacadbadbabdbbbacaaababacadbabddbdbaacbdadbaddbabdabdaacbxxxxxaadabadaxxxxdacdbcaccxbabaadbdaadababbbaaacdbaaccbdaacdadbcbdbdbaaacaadadbdbdaacbdbabbadaaacbadbaacaccabdbxaxbxdadaxbxxdbddadbaaaabaacdaaaadaacabbaaaabdbdaddaddbxxaaccxxxcxacaaxacbddaadbacdabdbdddbbdaxxdxxxbabadaaaxaaacdxxaaxaxxxbxaxbddbdbaaacacaaaaacadbxbbdbxxdxxxxxaaxbdbbbacdaaaddbaadbcbadababbxdaaaaabacbcaacdaabdbbbcdaaaaadbadaadxccxbxaxcbadabaaddaaacdaacdaaddaddxxxxxadxxxxabxbbdacabcaadaaaababxxxxccdxcaadabadaabdabaddacabxbdbxxdxxaxxxxbaaxbbxcxaaaababdddbddaaaaabaaaxbdxaxcxabxdaxcbxcbxxxxdxxxxabcdbbadacdaacdbbddaadabdacdabxbbxxaxcxxxaxcxxabaabxdaddaadaccadaaabdabadabadaacbdxxbaxaxdxdaxxbdxbacdaadbadbdbbadaacacbadaadbdadaacaaadaacdabcdadaadaccdbdadabaacabaaaabxaxabaxaaddaadaabadaadaababacdaaaabaaaaabadadbaaaaaaaabaacaacbdbaadadbdbxxdbxbxcaxxacaabadbdbaadaaacdbaaabcabaxxdbdxdbxabxxxxaaabddbaacdadaabacaabcaaadbxxabaadbdbdaaaaddbbadaabxdxdaaxdxxxaxxaaxaaacbdxxxabbaaxaxxaccaaabbbcaabbbaddacaxxbxxadxaaaxbbadbdxaabxxxxcbdxdbaxxaxadxaxaaaabbxbacaadbaadacbacdadbcdabadbxxxdbdbdbaxaaxacbdbdbdbababbdadbbbacacadbdabacbdaadbaadaaacabacdabccdaabadabbdaaaaaacaabadxxaxxaccaabdaacbdbabababaadacdbbbdaabbbaadbcbacacdbxdbxaaaabxxabxxxdxxxadaacdbdacacdbabaacbdadbdbxxbadbaaabbbdadabdbbbaabdbacbxdxxaxadbdxdabacabbaadadaaaacbbbaaaabbbxbdbxaxxdxdxbdaxxdxbxadxbdxbxcadbaaaadaabdaabdabxaxdbdaaaxxxbxxdddbabdbcbdabaabadababaabddaxcxcxdxxbxxbbbbxxxacxxxaacdxxaxdxadaxbdbxxxbxbxcbbbxxxbbaabaaxabdxdaaxbaaaxxcadxxaxxbaxxacaabdxxxxaxdaaxbacxabxdaabdacacdbdacdbdacbbadbacddbcdbabadaabadaaacccaabaaadbacbabacccbdxxbdbaddadabaadbdbabdadxxadacxdxbadxacxxxdxxxxadaxbbxdaxxxdbxxxxaxxdaxxbadadbxdxadbcbdbxaaxdxxbdbxxxcxbxabadaabxcdxacxbcxbxbxdxcxxadaaxaacbaaaxxbxdabacxxxaxaxbaxbxxxxbacbdacbdbdbdadaacbaabacdxaxaxdaadacdaxaaaaaacabxxxcaxbaadxxxxxxbdbxxaxaaxbaaaaxxaxacxdbacbabdbaadbdaaaaaddadacaaadaadbadaadaadaadbabaaacxxbbbxccxadbcdacdaaddbaadbbcaxxacdabdxxxdabxbabdxxaxxccdaxbaxbaxxaadbddbadbdaaacbabdbadbbdaxdxxaaxadabaacdxadxaxxcbxdaxadbabbacacddbaadbdacbaaddaaaxbacxaxaabcdbabaaaaaadaaaxdadadbddacacacdaadbadabdabbcacbabdaadbbcdadacbcbcbdaaacdbcdadbcabbbdbaaadaabaacdadabbcbxxbaaxdaaadbacdadaabbdabaaaxaaadaaadacababddadacdbbabdacaacbxbxaaxaxcaaxxxbbdbxabxxdbcadbbcbdbacaaabaaacabaabacdbbdxbaccaaxdxxbacbcdddddbdddaacbaabadbadadbaabcdacddbxaaaacxacbdxxaaxxabxadxxxdbabddaacddadacaddbaadbaaabdacdbddbdadbbaxbxxxabxbbdaadbdaaadaadacdbdacbaadbdaacacabaadbdbxxbxaddaxcxxcaacxbxcxxxxaaaxcbxxbxbxbxxbbcxbxbbccaaacbabaabdbcaaddabbabdbdacdaadbdbababcbbabxcbdadaxxbaxaxxxxbadaadbdaabaadaadaadaxdxaxcbdaacbbabaadaccdaadadbbdxxxxaaxaabxddaxbxxbbxdxdxabxxxadbdxaacbxxdabxaabadbdbbaacbbdaaadbbaabbdbcxxxadxdbaxbxxcbcaadbbadbadacdbadbabdacaacabaaaadaaacacdbxxbaxxdxaxacbaxaaaxdabaaaaadddaaaaaaacxbdaxdaccabxxxxbaxxxbcbdaaxbdaaacdacbdabccdacaxdbxbaaxxxbdaxcdbdabxdabaaxxaaxaxbbdxxxxxdxaxdaaccxaxbacadxbaxdbaddaaadbbabadabadacabaaaaddbdabdaxxxxbcadxxaxbxbadxaddbddabbabddbbaacdaacdbbcbbxaxaxadbxcaaaabacdadbadabbdaxadaabbbddbadacbaaaadbbadbbabaaacbaadadacdaabxxxbaddacdbaadbdaaaacdbbadaacdbxaabxcxxabdaabbaddbcadaadbbacaaaadbabbcdacacbbacacaaadbacdaxaxcdbaxxbcbcbbaaacbdaaacbdaacddbaabbcadbdbbaccbbdaabdaaaccbaaacdbacaddxxdadddadabacdbdacbadbcacxdacacdbaacbaaababaaacdacaabdbacdabbdxxbaaaaxaxaabbxacxxaxxaaxabdaccadbbaabdbbabbadbbabacxaacbadbaaacdaacbbcdaacxxaxaadaaccdaaadbbcaabdxbadbxbbaxbdxbxbddxxbabdxxxxabaadadbaabdabdbddacadaadbdabxbxxxxdaadbdbadaadbacdabacbaabaaddaaacbacdabbbaxxbaxxdaxbbaxxbdxdxaxaacdbbdaadbaadbadbcbaaxaaadbabacacbacbadbbadbaacdaadaaaadbaababbbadaaxxxddxdbdaxbxbaxxbxxxdaabaxaxcdxdbxabxxbdbxbaxxabcbxacdxxadbbbdaacdbbadbddadbaxcxxxaadbaaabacbaacdaaaadabdacbaacxdaaxxdbxxxabbcbaaabaadaabdbbadacdbbdbabaaabbbcbaaabdaccbdabacabaaabacaddbabddadabcdaadabbaxadxdaaxxxbxcbababaaxxaxdbaaxdxbdaaadaadaaaaaaadabcdadbaaaaaaaccdbaaaabadbaababxaxxxacxbaxbaaaabcdaaaaaabdadbbdabccdabdaabdbdaccaacbdbdbxdaacxcbacbaxxbxadabdbbddbdadaaaabcabadaabbdadaaaaadadxadbxxxaacxxxcdaacdbaadbdbaabcaxxbxbcaxbdacdbaaddbbacbdbbadbbdaaaaaxdxaaxxxdbbabcabdbcdacddbaadaaabdacabbbddaababcaaxaxdxcdacbabcaabaxxdacdbaccabbdaaaaadadabadacdxdabxxxxaaaacxxxaxcdbxxadxbabbdaadbdaxxxxxacaadbdaaaabbadbadacabdaacddxxxacaaaxxxadaaxxxbxaxbxacxxxdabacaxbdbaabadaaabdaaacbaaacacdbcdabdbdbccaaccabdaddaacabxxcbdxdxaxadaxxxxxadaxxxdaaadxbxxdxxbdxxxxxbcacxdxbcxdaxdxaacxxxxxacaadaadaadbabadabdbadadcacxaxxxcbxadabxxxxdaaaadbdaaaaacabbadaacacbcdbdbdxxxxbxaxaxbdbxdabdxdxbcbbacdbadbacbaadbbbaabbadbcdbdabcbdacddbcdbaadadaxxxdxadbacaddadbadaaadaddacabacbdaabdacdabadbdbdacadbdbdaaaacdbbbbbcaacbdaxcbxbxacbdxaaxxbcxdxabbdbdxbdddbadacdbaaadacdbaxxdabxxxbdaxxabxaaxbxcbbadaxxdaxaxabdadxxxaxdabcxxbxaaxxdxdbdacaaacbbdbdaccbbdbddbabadacdbdacadabbcaadababdbaddaxbcxbxadaxaxbcdaxaxccbxbbccdbacdadbabaadadbbadaaacdbdxdxxxaxxxabxbdxaaxdxbaxdbaxxxaaxaxxbcaaaaaaaabdadxdxxcaaxxbadxadbdbdbdacbaacdadbacdbabacdxabxxxxcddbbadbdacdbbaadbacccdacaadbbaabdbacabbaaabcbdaabdbbdaxbbdaxdxdxadxxbxaxbxxbxbaxadabbdbacbddaaadadacdbacaabbdacdbbadabdbxaxaxxxxdxaxaxabbxdxcaxxdxcbcdxbddbxabcxbccdbxcaddaxcaacdxxacdbxaxxxxxbdbcxxbabdabcxxaaabaxdxaaacdaadaacaccbbaacaacdbaabbaaaxaxbddacadaacbdbaaccabdxxxbaacbcdacacdabcacdxxxxaxbdbdxcxacdbdxxdabxxaxxdxxadxxabacbabdacbdaabdaaaacacbabaxcacdbdbabxxdbaadaccdbbxaxcxaxxxbxbaxbaaxcddxxaaaabxxbdaaaxaxadbxbxxxadacxacdbxxxxcaxbbdaacxdxcdadbdbxxdbdxxaaacbaxxdbxababbdxdbdbxbbccdxaxbddaxacxxcxxccdxaxxxxadxxaaxxaxxbxaxdadadxbdaxxaxaxxbxxaaxaxxxbxadxbxbxaxbcxcadbxaxxxxxbdabdacbbcbxddxxaabdabaadacabacacbbacbaabdbcaaadxaaaacacaabdaccbacaabdadbabcdbbabaacbabdaabdbabdabadbaaaabcdxxacdabbaxxbdbdbxxdbbbdxaxxxaabdxxdxcdaxccaxaaaxbbaxxxcaabaacbdbbbaabacdadbdbaadxbxbaxaaxbxxacbdadbaccaddbddaadaaxadaxbdxadadaacabaaaaxxadbxaccbxaxbbxxxdbaaadbdbcbadadbbccddaxxcdxbxdbdbdbacdaxxaaxbxxdxacdbxaaccdxbxbdbbxaadbxbdadacxbxxxabxxxaxaaxababbxxxxbabxdadbxcdbdaxxbxdxbdbdbxabadxxdxdbbaaaabbadabbabbaadababaaxxbdbdxcbcxadaaadbdaadaccacbdaaacacabacbadaaacdaadbaxbbaxaxxaxbxaaxxxababxacxxxxxaacxaxxxbxdxxaaxxxacxxxxdbddbadbaddxaccdbaaaaaacdaaxbbcaabdabaaabbabcbaabdacxxdxxdaxbdbadacdaxaaxdaaxxdadbadxxbxadxxdaxbdabdbadaaaabbcdbaacbddaaaaaxxbxaaaxxxbbddaxxxxcxxbbdxacacbxbxbxaaabxdbacbxabxxxxbdaadadxxcbaadabbabbbxdaxacxbdaaxxdbxaxxxxaxbaaxacaaabdbdbddaadbdddbdbdaxbdaxaacabdadxcxaaaxbxcaxxdaaadaxcaccdxaaxxdaabxxxbadacacbdacbcbdbaaaabacabaacaaacbdbadaaaaacdbacdacdaxxdxxbxxbdabxxxbxbaxaxxxbacbxxbadbadxabdxcbxxxdxcbbxxxcxaxbbddadacdbbaaaaadadacbaaaaaabbbdbaabaabaabbxbxxbcxadabaaabbaacaaaaacaxxacdxbxxaaxxaxdbxaxccxbxbcbadaxdaaxxbxxacxabaaaaddadacdacaababcbbaabdacaabaddaaabaacbaaaxbxxxxxxcbabbacbdbcbdbbadbaacabbbbaadaaaadbababaaadabbcbcaaccdabdaxbdxbxcxdxxxaxaxbbaxxbaddaacabacaaabaxxxaaxbxbabaaaxaxcdxdaaaaaadaaacaaaabxaadbxadxbbxcbxdabxadxbbxadaaaddabdabbacdaadbacaaadabaaadbababadaabcacbbaadaxxaaxxcdaadbadadadadbbdbdbbdbdacdbabcbbbdbdaaaadxxxadxxaxaaadaxdxxbxbxxxbbdxxdxabaxdbdaaaacaccadacbdacdbaaddbdaaccbcdaacbdbbddbabcabaccbadbdbaaabdaacbaadbcdxxdxxbdxxxbcddacxadxxxabdacacadaaaaxbxcbxxxdbacbxbbxaxadaaaxaxcdxdaaabdbadbaabdaacaccaaadacaxbxxaxcdbaabbdacadaaddbdabdbdbxbdxdaxadxcabxabbacbabbddacbaadbdaabaaxxaaxxabcddxabxacxxdbbaaadxxxaaxxacdxdxbcdbxxxaxaxxcbaxbdxcdaaaabcdaabddbbdbabbaacaabdaadbdbcaccabdadadacaaaabbdacaxaxbaaxxxdxaxbadbdaxacdadxxbbdxxxdxacbbbcxacxxbcabdbcbabbabcaabaaddaddabadbbdbdaadxxaxxdadaacxadxaxxxadaaaxdxcbxdaadxxxxxxabbdbbbabbdabbbabdacdbcabdacxaxaxxabbxbddadabacdaaabadbbdacdbddabdbaaxacdxxcdxxxxbcbxdbdbbcxxaaaxxadxabdbcbdabbaaaacdacddadaaaaxadaaxxcdxbxdxbddaaxaxxxaaxxaaxaxxaxacbxcaxdbaxxbaaxxxbbabxabxbbbaccdbdadaacaadabaadbaacdabdaccaaabbaadbaadadacxcdxxadacdaadabdacadacdbabbacaaabdaabcdbdbaadaadbaacddaabdaadbdadbcxxadxxxbxcadaaxdxxaxdxbxdbabaxadxaxdadabccbacbdbddaacbabddaaaabbdacbbaacdaabaxaxxxddbdacxxaxabaxbdbdbxxbaxxxdabxbaxaadadadadbdbaccdaabdbbaababbbaddbbabaacaadbdbdxxaxbxdacxadbabadadbdbadbaaabdaaadaacxadxxaxxdxbxxcxbbdxcxdbdxbcdxaxdbxbxaxxcxbdaddaccacadbdaababacdaabxacxcdaaaaaaaaabcdadacbbabdbxbdxbbbaccbacbddbdbbaacdddbbxxdbxdbbbxxbxxaxdbxdbaxaaxcadadbdacdaadbacabaaaaacacbdaaxxcxbbdaaaacddacbadadbaaacaxxxxxbadbaacbabxcdbaadbdbaadaadabdadabdaabaxxabaxbxxxaadxadbdbadaabdbadbdbadbdbdacaacbaacbdacbacaaaaxxxacbxabaxaxdaxaxdbbaaaaaadaaaccxxxaadabbababdaaxbabaaacabaadaaadacababaaaccddbdbbxbxxxxababbxxaxadbaabaacbdbbbbbdacabaxcdaxbaaaabaacbaaadabdabacaadxbbxcaacdddabxxxdaadacddbaaacbdaadddxdxabbcacbaacdaaaaaabdddacaxxdbadxxxcxaxadbaxxbbbaxdxxbxcxcxbdabddbabdbdabbaadaaaadacadadacddbddxaxabbabxbdxdaxxxcxxxaaabcdbdbdbdbadbaabdaaadadbacbxdabadadbcaaababbbcaccbbxdabxxdxxdxacdxxcababaacdacbbabdadacdaacdaacaaaadbxxaxbadacbdaabaaddbdbbadbbacdaadxdxaxxxxxaadbxbxbbxdaxbxxdbbbacxxdaxaxdbdxdabbxbaxxdabxabaddxxaxcbacbcabbbcbabdbaaacaababbddacaacbdaaxbxacaxaadxdbbabxcacaacadaaadaadabdbdaadxdbxbxxaxdacxxdaabdxxaxbaxaxxxcdbddxaacdbccbabaddaababbaxxcbccxxaxaabaxacbbaxxxxaabdacxaababdbacdadaadabacaxdaaacdbbdbaaccbcaaaaaddbaddadaabxxdxadxxbxbbcxxbdxbxcbdxaxaxaxxccbbababbaaaaaacacacaadaccdabacaabaaxxxbxxdxxadxaxacdabbcbdaaabdadacbdbdbadaadbbbaxaaaaadbdaccddaaacbbbbbababcaaadaadbabacabbdbbaadabacdbdxxabxdxxxxccdxdaaaacbbbdbdaabddbdabbdbaaaacbdbdaabacdacdbbacxxxabcxdbdxacxxxdxxacdabaccbdbbdacaadaadbdacbbaaaccbaacddbdadxxxxdbxxxaaabacbdaxbbxxaxxxdbddadadbaaabdbdbdbaaddbdbddbabdadbadabbbadbdbbaabacxdxxxbaaddaaacxaxbacdxxdxaxacbabaddxxbdabbbdxabdxdxxadaxxaaaaabcabacdabddabadacadaaaaacbcadaabdacxxxxxxaxcxaacabcacbdbdaacaacdbdbaaabdabdbcbacbaaaababdadbbdaacdadadbabbdadaadaaaxxabaaxddbaaaccxxaacxxabdbaabxxxxaacbxxxdbdbadbdaadaadabdbdbdaxaacdxaaxaxxbdaxdxaxbdbxddxcxadaadabbbaaaabaaaacdadbabbaxbxaxaacaabaaadaabdbcaacdbaaadbdbacdaaaddbabacdadaaabaxaaxaxacbadaxdbaaaxxbdbaxdacxdbdbaabdabdadbdbbacbdbaaabxaccbadbbbbdbacaaacbacdaabdaaaacxbxcbdxcxdaacdddadacdbdabaadadbdadadaabadaadabdbabcxxdxaxaxbdbaabacdbabddbdadbbbdaadaaabadaadbbaaadbdbdadadaaccbbaacbdbbdaabdaxbaaxxbcaabaxbbxxdbbadbxdbxxdabxxdxdaaabacdaaadaaaabaxaxxxxxcbxdbbaabacbaabaxbxbxxxcabxbdabdadaaaadacdaadadacbaacbcaxaxxdaxaxxaxbaxdxxdxxdbaaddxxxaxacddbaaaxxdxacbdaadbadbdadbadadaabdbdbaaaadxadadacbbddabacadaadaadbxxxdbxdaxdbxdbxxdadxcaacdadxadxabadbacbbdaabdacabbxxaxadxxbbbxaadaadbbaccbaddaaaabaxdxaxxdaaaxxxbabdabxxdbaxxbxdacxbdxaxdxabxxxcxbbaaaxxbxdaaxdxddxaxxxbaacaaaacddbacdacbdbaadxxbbdaabaabddabaabddaaabdbdbdacbdaacdabaacxadxbaacbbbbdbaacdbdbdadbaxxdbbxxaxxxbdxacdaxbacadaaddbcbbaacbdaxaaxxbaaababaaaaaddaaxaxxaxaacdadabxabbdadbadadabdadacbbaxdxbaxxxdbabdxdxbxdxbcaxxaaxadbbaxcxacxacdbxcdxbdabdbbbaaaaabaccaaabdxdaaacdadacaaabddbbadbxbdxadxacdbdbdbdadbaaaaaaaabbcbaxbacxxaaxxdxcxdabadacacbdaabbdbbbbxaaxxcaabcbdxdxbacadabdxacdbxdxaxdaacaxacdxxabxadbdbdabdaadbdbbacbcbbdbxcbxxbxxbxdbaaaaxdxxdacbcbxxbxxccbxaxbbxxaxadadbbacacaacdbacbabcbdadacadbaaxxxadbacbcabbddabdadabbcadbbabaaaabaadaddbaadaabdadadbdbdaadbbabxbxbbdxbxaxxxdbccadadbadbabadbaadbdbxxaxxadxbbaaaxxxxdaxdaaxdbxbbxxcbxdbxadacdbxcdxbbbxxxacdaxaxbxdbcbbaxaxbxxbbxcabdxdxxxdadbxxaxxdbdxcxaaabacbdbdbbdbdbcbaddbbbbaaacdaadaaadaccbdacdbaadaacadaaaxxdbdxxcaxdxddbdxaxcadaadbdbdadacdaaacacdddxcbxxacxxbxxaabacdaabbaaadaaaacbbaddaadaacbdbdaacbdaabaaaaxaxxaxbxbbxdxaaaaabdbadaaabdaaacdddadaaaacdbbdaaadaxdxaxabbacacaadbabbdbdbbadadbaaaabbbadabbaaxacabxdaaxddxaaaadxacdaaabaaabaacdadbdabaaxxcabadxacaaacacbddbbbdaabbdacxxxxabdxxxabaaaaxadbabdbdbcabcadaaacadbddaaaaabaacbdbbaddbbdbaabaadbabacdaaabbaxadadbbbabdaacbaadaacabdabaacbbxabdaaacbcaxaxaxxcxbxbaxbaxabacaadbdadbaaddbacabaaxbdaxxxbdxxccdbxxxxxbbadxdbcbbdabadaccbcdaabxaxxbbxxdaxaaxccdxaaxbxdxababaaccbacadaadbaadbcbxbbxcdxxcbxxaxxbxaabxdxcbaxxaxxbxdabbxddbaxxxbxxbxxbacbbbbdadadaaacdabdaaaaadbdbabdacdacbbcbacacddaxaxxaxdbdxaaxbaxadxxbabxxxxbdbbccbbdacbbdacadabcaabdaaacbacacdaaadbdadabdacbdacacabdadaabaaaacddxdxdxcddabadadaaadaaaabacdxaxdbxbxxbdbcbbadbbdaccadaaabcabadbabacccxacaaaaabdbcabxdabxbbcabaaxxxaxdxcadaaaabababaadadacbacabaacdbbbdbdbaacaaaacdacbcababbdbbdaacdbbxdaaabxaxxabbaxadxacbadxaaacxdacaaxbcacdacddxbxxxxdxxbaaxaxabaxbacxxbacdacaaadbdadadbdbdaccbaadbabdbdaaaaabddaxdaacaxxbcxabxbxxxccxxbdbxcxxbaddacabdbbacbdabdbacxxxxbaddbdaabdbbabdaacbadacbcaadaabadacbbdabadbcaaadacdddxdabxdxaxdaccaabbaxcadaxacbacbaaabdbdaddbaabaxxcbcxcdxadxbxbxxddabcxxxdxcdadaxadxdaxdaxcxxxxxxdxcxxxxcaxbbbcbdbdbbbadaabbaabbdaaaaabbabacddaacbacbdbddadaddabcbadacaaacddaacaadabdbbdbabaaacbcacdaacdbxacaxaxacaxadxacaabbbabababdacbadacccdbdbcddabbacdaadbcdbacbbbddaxbaddbxaxxaxxxaaadxbxxdbxdaaaadbacxxbabaxbacaxdxxxaxaxbaxxcxxacxaxdbcdbbdxdxcddxaxxxaxaacxabbbcbbdaaddaadaaaacdxaaxxdxaaaxxbacxxbbdxxaxcxxbxabdabaxdabddbdaaaaaabdacbdbacdbdadadaacbdabbdacbadacaaacabaddxcdbdaaadbbcaabacaabdbadadxdaxxbaxxbcbdaacaaacdabddbcdaccdaaabaabbaabaaxxacaaaabdabdacaaxbaacacaabbabdaccabacdbdaddbdbacbdcaddbaaacdbdacbcdabxbdbaxbxxadbcxbdaabxdadbdxaxaadxaacaaaaxxxaxdxdaaacabaxaxbxadxabxaaxcdaaaaadabaacdddbacdaaxacccxbaababxaadxbdacxddxacxaxxbxxaaabdabdbadabacbbdacxcdbaaaabacaaaacaababaabcdacdbaadaaaaaacxadxdxdadxxxaxxabxaxxxcaddadbdaxaxdabxadxxxxbdaxxxxadxbabxaabxbaxxdaxbbdbdadacadabbadbaddadacacdaabdbbdaadadadabcbbbbaxxdxxaaacxxdxaadxxbaaaabdabaadbaadaccdaadddbadbcaacbbdbdaabdacccadadbcdaadbabbbadadbadadaacacbabadacdaacacdbaaaacdaacbdadacbdaccdbaxxdbaxbxaadxbdbxbdbdbdbxbcxxxcxcabaadadbadaaaabbdbdabdabxdbbdaxcbxaaaxdxxaaccxaxxaxbaxaaaaxxxaxdbadacbbdbdbddaaaadaxxcxcdxbcbdbxabbdbxbdaxcccbxbxbxxabaadxbdxxxbcxxxddxxadbxxaxxcxcbxaxabcdaaacbaaacaaaadaaaabxaxcaabbaabadacbdbdaaaacaaabaccbdacdbccdadabbcbcbabdbadacdxbxxxcxadabdxxxxxxxadxdxaxdxcdxdaxbdacxabaaddbbabaaaaaacbaabbbbbadxxaxbaxdbxaaxabacabbbdadaaabdaacabadaacddbacdbbxxxbadxxadxxxaxxaaxadxxcxaaabbdacaxxcbbdbabdbbbdbddaaaaxxccxdxcxaabcxaxxabdabdcadaababacdbabdbacxbdxadbaxxxaaadxdxxdbxxxadbbdadbbdxddadbbdbadbdbaaaadacbbadbxadxbdxdbadbdaxdxxxxbbxdxxbbaxxxxdxbcdxabbdbaadbaabdaadacababacxdbdaxxxaacaadaadabaaacbcaaacbacaacdaaabaaaabbdbdacbaabaxxbbdaxxcabbacxxxxbdaaxbdabaxaaaacxcaxxxxcaxxabdxcbcabdaacbbaaabdbbdbabadaadbaaddabadadbbdabacbdaaacdxxabaaaaaaabaacadaxbbaxxdabbdabaaacbdaabbaaadbdbbbdaadbaacdbdaxxcbdaxdaacddxxbxxcxbdxbxbdbaaccdadaaacdaaccdaadbdbaacddaaacdbabdbaaadbabaabbadacbbddaacbababbxdxacbbdacxxxxdxaxxbxbdacbdbxxaxxdxxdaaxbxdxxacdaaadbabdaaabaabddbddaadbbadacdxdbaaxbxaxdxaacaxaxcdxdbdbdacbacxaxxdbxaxcabbadbdbaacdadbdbdbbdbabxbaaadbxxaaxdbdbccdbabbacadaaaaabdbdxdbxaaxaxaacdacdacabdacdbacaaacabacdbabcbbdbaaacdbbabbbdbaadbdabadxxbbaxxbaxxccdxxabxbbxxadbxaadadbbdbaddbdadadbbdbbbadaaadaxxxcbxbxaxcxdabaaaxxxxxadbddbxddxbdxaxxaxxxxaxcxdaadabadbddaadaadbadacaxbabxbcbxxbxacbxcbxxbcbacbdadaacbbaaaaabaabdabaaabdbaacadbdaabbaadbabbadbaadaccbdadaacacbdaacdabdbabdaxxxbxdaadaaacdabbaaaxxxdbxbdaxabbacddbdacabbaadacdaxxxxxadbaxbdxaxbxxbdbbdxxbxbadaxxdbxaaxbdaxddbacddxbaaxdaxbxxxbaxadxxabdacdabdabdadabdaaacbaxaxcdxxxxaaadadbabdbaaabdbbcaabaccaxaxdaxdaxbxxacxxaxxxaxaxxddxcdxdbcdbaaadaaaaadaadbacadabaaxaxaxdxddabbbadbbadbcabbdadadacbbadxxacbabxdbbcxbxdxxxxxxcxaadaaaacccabdbdacbdaaaacbbcbacdaababaacbdbbdbbdaacdbaacbdbbbadxcdxaccbdxxadxaxdaxxxbxxabaabadxbacdbxbccdxbxxcbcdbbxxxaaaxaaxxadxbbbacbbcabcabdadbbadaaacbbbbaacbdabaadbabdabdaadbbaacabaxadbxxbbxaxdbaxdxaxdxbbdbdbbcabadacbaadbaacadbdabcbaaadbcaabdaadaaacaaxaxccxxxbbbdaadabdbabbdbcabacaabdbdbdbaxaxxxxdxxxaxxbacaaaacaacdaacbadaabddaacddbdbaadbbaaaaabaacaababddbdbxxcxadbaaabadbdaadaaababdbaadxacdbaxadxbaaxxxdbxbdbxcbbxxabdxaxdbxaaxccdxacbxacabdaabcdbaadbbacadadabbdbcbdadabddbabbdbadbcaxxadbbcbadaadaaabdabadbbdbaadacbaxcaaxxaaxadaxxabxadbaaxddxaaadbcxxcxxxxaxaxcbxxcxxdbcbaxdbxxbaxxaxcbabxaabxxbxxaxacbxxabxbxacxxdbxxcaxxaxddabdbxxaadbdadbdddaacccdbccbadaddbacaaxcdaadaaaaaaaabbdadaaabaadababaacbbdabbbacdadaaxxbbabbdaaadabddbbbadacbbbaaxxxxxxbbaadacaaaabbdabbdadbabaaaddbaccaxxbxxxxbdxbxdaxacbxdxxdxdbbadaabxbddxcdbdaaxxdxaxdxbdbdaaxxadxxadbxacxxaddadbacabadaadaaabaadacacdadbabaccxxxxcxxxxbxaaaaaxacbdbdadabacccbbdbbaacdadaadbaadbbabdaacadabaabadaabacaacadaadacddacbxaaxcaaxaxcdbxdxdbacxdxxxbxaxxxdbaxbadadbaadabbdbbddaadbbdaabxxxbbxbdxddabxxaacdbaddaaabbaabbdacdbdbbabbdxdxxxdacxxbdxacxaaxbxxcdxadbxxaxbdxxxxxbdadaxabxbbxxxxcbaxbbaccabdacbabacbadaabaadbdaacaccbbaabddbcxxxbxxbbaxaacxaxadxacdxbdabdbdbaabaaccbaaaaccaacadbcbccbdaadabdaxbbbaadxbxxaxdacdabadacaadbdabdbaacdaadbaabaccbbaacacbaadaaaaxxxdxcxaxxxxbddxabaaxbacabxdxxcdadaxdbbbaxxxdbaadacbcdabbaadadxcxxdxxxabxxdbxcdadxaxabacadxxcxadbxdbaxadaadacdaacadabacddbbxxcxaaxxxabacbddacadaacbadaccacbdbdaaabbdbcdaaabbacbbdbcabaxacaxdxdbxxdbcdxxxbaaxcaaacbddbccbxaxabaaadxadacxxxddbabaaabbaaacaabcabcaacbabccdacdbadaxabxcbxaxadxxadbxaaxxaxbbbdbadaxxxaxxdbxxbadbadacdaabdadbdbdabaaaaacdaabbabaddxxdbabadbabacadacbaabadabdaaadacdbcdacbaxbxxbxxxxaxxbabbaaaxbaxxxaxxxcccxbxabcxbaxxxacxxxxcbbadbdaadbcaaaacdbdadacbaxxxaacdacddadacbadbdbcdbddbcbaaadacaabaaabacbacbbabbaaxdxxxdxadbcbaaaadbaacdababcdabaadbdacdbdbdbcbdaaddbbaaadbdaaabdbbabadcabaxdacdxaxdaxxcbdaabbdbxbdaaddadaaabaaacdaabacaaxcxcbbaaxcbbabdxadbaaaababacaabaabxaabxadbcxadxxxxbadabadbbacdbdacdbaccaadbbabdbcabdaaaaaababaabdxxbdaxdxxbxaxxxacbbbdaadabadacaddaddaacaacdaddacaabaadbdaabdbdbxacdbacbbbbbbacadbdbacdbbbaadxxdxcxxcxxacddbxaccaaxddxadxxbdxaxbaaaaacbadabdaaaaaaaddbcdxxaxaxxdbcaxbxbxxdabaacdabdbbbacacdabbdddaccxxxbdadaacbaacabdadacbaaaacbbbaxbxddaxadaxxaadbdbdadacdaabadacdaxaxdacdaadaaabaadaabadxxbxcaxdxcxbxxxxdacbddbxxaacbdbacddadacaacccbdbdbbadbdaabdbdbbdadaddacbbcbbbxcdbacbaddaacbddaaadbxdxxaaxbccaaaabaacbdaaxbxdxxcdxxdadaxaxxbxdaabxxdxaaxabxxaaxdbcdbcdbaaaacadaabbdaacbbbbacaaadbbdadadadaaaabadbacadbbbbbadaaddabacbabdadaaaacdbabdaaaaaabaaccdbadbdxaaxxbxbxdxxbxxxdbaacddacabxabxaaxxbdabxxxbxxbxbdbcdxxxbxdacbcbacaaadaaaadaacaaadbdbdacbbdaaaccxaabadadxaxaxaadxcbcaaaabxbbxbaaaaaaaaaaaaaxabadadaababdbdbadbbxcaxbbdabbcacxxxxxxxcbadabaxxxdbxaxabxadxacdxbxdadaxaxbdddaaacacbbdbadaaaaaxcdaaaabacaaadabxdbbaaaabbabcdbdadabdbbdaacbcdaxxabdbxxxccacxxxaxxbabaaabadabdbcadadbabbabdbdaacddadbadddbdadaaaaadbadbdxxaxaxdababbxaxxxdaxaxbbxacadbxbdaabxxcbxxdabdadbdacbcadaaadadbaacxadbxabxaxxxxbacddbaddadbabaaaacaadaaacabdaadacdbabadaaabxbdbxbbdbadxxbxadaaadxxabxacdaaxaaaaaxbxxbbaaxaxxxxbcxcbaacxaxbabxbdxxxxbabcdaaabccbcbbacbdadbcbdbaadaaabacaaadddbaacxxcxxcaaxxaaxxbdxbbxacxacbbacbxaxadaaxxxxcxaaddxbxaacbacdacdadacaacdaaacdadbdbdaacdbbbbbaadaadbxacabaaxxdxxxaccxdxdaxacdxxcxxbaabcbdaacabdaabdaabadbxbbaxaadacdbxxcdxaxaxxxbxbaaxacxdbaxxbbxxdabbaaabadaabadabdadabbacdaaacddabcbcaaadacddbbbxbaaaxdbadaaccbdaadaacabacaacbacbbdabdbaadabdbabaacdbaxxaxcaaacbdaaaadaxxacbadbbddbdabaaaaaaacbbdadaddaccdxxxaxbbaadaacxbacxacadxdxdbdbxcxxacbcacadbcabcdbaadaadbacacbdbbdbaadbbdbccdbdbbaacaabcabbxdabxaxbdaxbdxxdbxxbxaxaxxaabbxxbdxxxacbabxxcdxxxbbaxcbxxacbbaxxxaxdbxbaadbabcaccdacaaaddaaadbbdbbxababbxbxxdbdbaabxdxdaxdbcddbabxabxcaaabaxxdbaxaxaxdxbxxdxaaxxxxxaacbdbadaaaaaadaadadbdacxdxdbxaxbaaxxaxxxcbdxdbaacdaaacaaabadaaabdadadbaaadaacdbbaaadaabdadaaaadbdabaacbdbbdbbbacacdbcaxxxbbxxabaadbacdadbdbdabcabacdaaxbadabbxxxbxabxdaxbxaxbaaaabdxxcxbabdaaxxaccbdbaaaaabdbdaadbacdxacxxaxxaxbacaacdadabdbabcdbadacaadacadabaababbabbaaadacdaaacbbacxxbabdbbdaxaxbdbxdaxaacdbacddaaccbaacaacaxcbaaabdxxxacdacbcbaadbdaabaaaacxbaacxxabaacbxbaaxaxxacdabaxaxbaxbdbacdbbdacbaacdbadxcbaxbaaxdadbdaaaacdaaaabaaddbabaaxabadaaaaaaabbdaddadabxbabaabdacdbxaxbbddadxadaxxxcaxxbbabaabaacddabcdadaaabxdacccxxxaaaxxabadaxcddbxbaaacbxdbxacbacxbaaacaaabaababbdaadabbxdadxcxaxxxaaaxxbadxadbxccxbdbdaaacdbcdaaadbdadbddbcbbdbbbdbaabddadacaaacbadbdadaddbbbacdabdbddbdaxabxxxbaxadxxbxbaxaxxxacbacdbaaaadaacdacaaaacdaccaxbddbddbacdadbbdacacbacdaabcbaaacaxabxxxcxxxdacbacdbcaacbdadadaaaadadbdbadxadaxxcxxabxabbxdxaxxdxaxdbabacddabcadbdbacccaaadaaddadbbdbbbbcdaacbabaxabxbbddbxdxdxcabdbdaababdbdbdbdacaacxxxaxxbacadbxbabaaxaxxxxcdxxaaxxacxaxabaxaxbxaxaaxbaxbxcxxxbxxxbdbxaaxbaxbaxdbxaaxbxacdxaxxxacxbxxbaxdbdxxdxbcaxaxbdbaxcxacxbcaabbcbaadbaadbaabaaadbaccacdbxxxxacbxbcaaxbxxxxabdxaxxxxbcxbadbaadabdbacdbdbdbbacbabcdbdbaaacdbdbaaaacdxdbbxxxdbaadxaaxcbxabbdbdbbbaddadbacdadacdadaaadacxxdbxadabdxaxxxdxaadxaxcxcxaxxccbxxxxxadacdbacdaabacbbbaccbdbaadacaaadaaacacabdadacbxacxxxxacdaaxdbbabdbdaccbbdbacbbbbadxxxdaaxdxxdbxbxabcxadacaacbdbaaacbdbdbaxdaxxbxbxbxdxcbbdbxbdaadxdbdaadaaaaaaabdaabdadbbdxdbdaaadbdbdbbdbbadaaddbbaaaacadbabbdbdbcdabacbdaddaadacdddbdacaaaxxaccdaaaaabaaabdxaaxxabcdbxxbcxacaxaxdxaxdxdxxadaacdbxacxxxxaabaaddaaacaaaaabcdabadxxxxabbxxadbadaadxaxaacbdbdaacacacacdbabadbdadbaabaxxdbxxcxaaxaxabacaxxxbxxaxaxxdacaccadaabbcbcbdbaabaacdaaaaacxaaaaxaxxaxxdaabdacabbdaadadadadaaaabccdxcdxxdxxacaaxbxbxaaxbaaccddaaaacdbdbdbaaabaaacbdadabadbabaaacdadbaaddbxxdbdbxbxbdxcxxcxaxxxcxbaaxdbbxaaadxcdaxaxaxacdadadbaaddaacdaaaaadadbbbdbbdbcbxxxaaaadaxdbdbdxaaaxxxcdxbxbbaxxbxxaxccxxacxdacdxxadbbbdbcdabaadbabadbadbdabaaxbbdddaaaadababaaddbadaccbbadbabxdbacaacdbdacabdadbdabddaaaaaaccbaaxaxxbbxxxbddbaxbbxbaxabbaabadacdadaaacababadbdacbaabdaabaccabaaxcxaabxabaxaxxabdxaxxaxacxxbcxxdaxdbaddaxxaabxcxddxaxcacdaaxbaadbdbaaabbbabaacdaaaadbdbdaaaaaabbdbaxdxcxdxxcxbxabdbcbxxdaxabaxbabxdacdbcdbaabcaadbddbcaabdacbxcxcbxbxxxxcdaxadaaddbbaccbacbbadabbbxaxxxbdxxcxbdbbabaabbbbcadbacdaabbcdbabbaaaacdabbadxxxxxbxacbadxdaxddxbdxxxbdbcaadbcdbdbaaaabxxxdadxbdaxcabxccdacdacadabdabacacabbbbbadbdacaaacdaaacaabdbdabxxbbacdabadbbdadadbdaaadadxcaccxbxcxadbxcbaaaabbaabacaaxxaacaxxdxxxcadabbdaadacbdbaabaaaaccabaacbabbadadadacdabadbbadaxxaaaaxadxxxaxxxaxdxdaxcbdaaaaaabbaaaccccaxdbabadaaacaacdbddbacccacbaadbababcbacbbdadbadacddbbadbbaacbabdbadabaxxdaadxaabxaxbdbxxdaxbxxxdxxcbabxdaaaaaaabacacdabbadxadxxxbdaaababcdabacdaaaaabcaababdxadbdbxxabxbxxacxaddaxxxdxxaxxxxaccxdxccaaaxaxxdxbxxaaxbacaaccxbxxxaxbxxbxaxbdaabadbcdaabbbdbdaaxxbxaaxxxbdaaddbxbxxaaxxadaccdbabaababcadbbbaaaddabacbdaxaaaxxaacxxbdadaaaacdadbccbdadbbdbcdaaabdadbaacdacbbxbxadxbdacdxdxxcbabaabdaaaacaadbdaaadbaxbxbacxbxcbxxbdaxbcxdaaacbadddbdbbdadaacbdadabdabdbcaaabaabdbddaaadaabaacadabdabbacdaabbabdaaacbdbbaaabdbabdbdbdaabacdbaxxaxbacbxxdxaabxcacdaaacbabdacbaaadbdbaababdaaadbadaabacdadbbxbaxaxbdaaabacaaadaabadbcbaaaabcaaccxxxbxcaxxxxadxdacxxaxdabaxxxddxdxcbxxdbacadaacadaadabdbadbdaadabcbbdaabaadabaadaaabadabdbabbxaabbadxbxabdxxxxxbcxbbbxxdaxadaxbxaxaacbcdbdaaacaacbacdabdbaaaaxxdbbbdbbadacdacadbdbdacacacdbacacbdbbbxxxbxxaxxbaddabbdacadadaaaacdbdbdxdaacaxxbxxcbaaaxcdaacaaabbcdbdaabacacbdaaacaxxdadbaxbaxxxxcxxaacdaxacadaaaabbaaabbcbacbdbabaadbabdaadbaaadbaaadaadabbcxxbaxxaaxddaaaadxaxxdbxaxdxcdadbxcbaxcbbaaaxbcxdbxxxaxxabxdaacxxxxbxbadadbbxcddacaabadbaaaaadbdaacbbxdxbdaxddadaaxxxbcdxacxbbdadbbbaaxdxbxxbdaaxxcbdxcdxxcdbabdbcdbdbabdbdaaacabdxbbxxbaxxaaxxdaxxcdbcdxadbdbabdacdbdbaaaaaabaadaxbbxxxadxxxaxaaaaxxcacbdaaadbcdadddbadbdadbdbbaxaxcxdxbbxxxdabdaaadabadabccadaabcaxbdxxacdbdbaxaaaacdaccaadxxaxdxxxxcaaxcxxaaaadaaaadaacdbaaadbdxxbcadaxxxaaxcacacxxaxaaxdaadxxxxaaxaxdxxxacbbdadbdaxxxaacaabddabdbdadbaadabdadbxbbxxxaacxbaxxxaxxcdbbdbdbbbbadacbcadxabxxdaxaxdacbdbdbxxxbxcadbbdxdxxdbxcdbdxxxdadaaadbbxbdaxxbxxacbadbdaabdbdabaacaadaaaacaaxaababbaaaabaadadadbbdabadbdxaaxdbbdxxaadxcbxaacadbxddddaabdacaabaaaxxdbaxdacbdadbdadbcaacadacbacbacdacdbbacabacdacabaadaabbxbxbxbaxbxaxxxxacdbbacacbbdaaaacdbcbxdabbcacbaaadaadbdadadbbxxxaxbddxbxxxdxaabdbdaaabadbaadaaaabbbcaaaacdbdabaacbadbbdbadaaaacaababdaabaacdacdabdbdaaabbdbcaxxdbdacxddbxbdxxdbdadadaddaaaccacdadabxxxaaaaxaxxxdxaddbdbdbdabbbaadaabcdadaaaaaxcxxxxbccxacxcdaxbxcxdxxxbacbdbxdxbdxaddxaxaabxbxxbxbxaaacdaaacdaaaaadaabbadaacdacaccaaaaacdaaabdaxxxxxdbxaxbdbacaacbacbbadaadacbbaaadaaxacdacaaabbdacdbcdbaacdaadbacaabbbdaabaaxaxacaxxaaaxxdadbxabaxdxbaxxxxcbaabbdbacddbaacbacbbabaaxxdxxxxdbaaxaxbxbbxdbxabxabdaxxxxbxcxxadxxxbxcxdaxdbacxcaxaabxxbxcxxbxdbcdxxaxaaxbaxxcdbaaxdbaaaaadbbbadadbbacbadbbaaacbaxabxacbcxaabaxxacxxxababaxbadbbcdxcccxdaxdxxdbaxabdaaabaaxbdbabdacddbacdacdaacbbadbdaaaxaxcdxaaabbbbabaababdbaabdaadbdaacbxbxcdxcdxadaaadaacabaabaacacdaxdxaabxcxabadaxcdadaxxxaadaadabaaabbacbacaaabdabadaadbcacdaacxxcaabdbadbadaaadbcbdbxbaaxxxbaxxaxbbdbxadbababdbddaacadaaabbbddbxaxaacdaaabbxaaacaadbaadabdaaaaababxacdaaaabaxaaxdxxdaabdaacbdaadbbaaadbdddbbdacbdbbdabbacbbacdbabdbacbabddaacbaddbbdaacbbacxcxxcxxdxbdxaxadaaxxbaaddaddabcdadbddbbdbaaaaacxaadabaaacabdaaaaadaabddabababbabcdaacaadaacbadabbadbaxdxaabbxaaddxxxcbxxaadxxadbaabaaacdadababaddbcadaaabbbaacdbdbaaacaabacdaxdxacaxxxxxbbdbacxxcxcxxbabxxaxdbdbdabacabdabadaaaaddaaaddaadbdbdaadbdaaxxadxxxadxxbcbxcxdbxacbxaxdabbxaxxxabdadxaaxxxaxabaxbdbdbdbcadacabdbabbbddbbbaaaaadaacbaaaabdbaaaacbaxxaabadxxcxaxxabxcxbxxxbxdacbacxxxcadxdadbbadbbaadbdaabaaabxbbaadadbcaaabaacbaaadbbaabaabdbxxdxadaaaabaaadbaacdbdbacdacdaacdbacdacdbdaxbbdbbdbacdxxbbxxdxcdabbbdaaaaaacxaababaaaccacdbdabacbdacdaaaabaaxdxdabcxadxaxacbcbdadxxababddbbaddbcabacbbdbdbcbdacbdabdaxxxxaaxaxxadaabcdaaxbxxbcdbbxxbacbadaadbbdaaddaaabaxadadxdaxxxdacdaabaxaaxaxbxdxxaxxcaxbacdxaaxaaxxbadxaxxdacdbcxdbadbabxbacdabdbaaaacabaabdbxxxddaacxaxxxxaxxbbxaccxbadaaabbbxxxxcxxxxaaadabcxaxbxdaxbdbacdbbcabcdaaaacdbbxaxaxaxbbdaxxcacdbxaxxdaaxxaxacdxxdbadxbaxbadaadxbdxababxabbcaxaacdxbaabdxxcdxxxdbxdxxadacdabaaaabadabcdddbaaabxaaadxxdaxaaaabdaabaaabaacddadacaaaadaabdbaabaabbccabadaaabdacdbdbacxxxdxxbxxxdaaadaaxxcxbxbcdaabbadadbbdbaaacacacbbadabaabccacacbdabbacaacbdadaaadaddbabbdacaxxxxabxxxxbxxbddxxxbaaxbdbcdbbbaaacaadaacdxxbadxdbxxxbbxxxaaaabcdxaacxxbaabdbacbdbdbbbacbdcabxxxacaabbdbcaaacdadabbaadacbabxaaxbxaxxadxxbxxdbbdxdxxaxxbbbxaddxaaxxxaaacdxbccdbaabaaadaabcxcbbaaaabbdacdbbbcbadadabxxaxadaxaacxbcbbxxaaxacaaccdacdbaaaacbaabcbdaaxaxbxxcbbaabdbbbaadadabdacaaadbbbccacdabdbdaxxaxbxaxxaaxxbadbaabdbacacddaaacaadabaaabdabxxaxxxxxbdbdxabdxxxaccxaxaacxadaaccdabdbdbacbbabaaaxdaxaxaxdxdadaaadaabdacdbaabdaaacddbbbdabdbcdaaabbbaacbbdaaddaabcbaxcxxxabdxxcxxbaxbxxxxbxbbxaxbbdacxdxcaadxaxabxbbaxdxaaxxbaaadaadbbaadaxxaxxdxxxxxcxbxdabdaaxxxdbacdabdadxcxxaxxdadaaaxabaxxxadabababxaxcaxaaxccacdbbdadbcdadacbdbdababcbbabaabbcdaabdbdbaccbaacbdbdbdbcaddaaaaacdxdxxxaadbbbcxacbdaaccaaaacbacadbdbbbaababccabacbbdbddbaccadadbddababddbdbdaxdadbaxcxbabbacxbadabadxbxdabacbcdbcadadacabadbdbaxxxaxxaadaababcbbaacbabbabaaacacdbcbdbabdbcbbbacxcxcbbxxxxxaaaaacdbaacdacdbbaaabaacbadbabadaabdacaaacdbbaabcaabxbxaxaxxdxaabbdaccacdaccbacbabcdbxxxxabaxbaxxdaaadxadxxxxbdbaxxadxxdaxxbxdbdabbbbcaaaabadadaabcbacxxxxaxabaxdacaxxdaabbbxxdbcbdbbdxaadxxxaxdadxadacbacbdabacbaaaadacaxbxxxbdbbdaxxbabaxbdbacbaabbxdxaaxbxaabdbxdbdbxabxaaxxdaxbxdaxbaaxddxxcxdbaabadacbdbbbaacbaxxcbdaaxdxxbxabdbaxaabdbbxacxxbaaabxadxbbxbabxxbxxxxxaxadxbdbdbxbbdbcbdbabbdabaaaccdbacacbaaadabdaabaadaababbdbcdadbxxxbxacaaaaabxaxxdacccaadacbbbcdbabdxbxxxxaadbxaxaacxxadbbdbabacdacbabdbddbabdbcbaacbxcxdabxdadaxbxaaabdbabdbdbbddabbdabdaabbaabcbdbdbdbaaadabaaadbdaaddbabacadbbdbbdaaaaaddadaadbdaaabdaabaadxdaaacccdbacbaaccddaaadaacaadacdaaabaacabadaaddaaaacdaaabcbdaadxcbdaaxxcadacdacaaaaaadbbbaxdbxbaxbxxaacbbaaadbabbdabbacdbdbcdbxxadxxdbadbaxaaabcdacbaaddaaababdbaacxbdxbxxdaaxcabdbacdbbaadadbaaacddbbaaaaddaacxxxxddxxxaxxcdxcbbxdbxcdxxcxbdaxbdxaaxxxxbxaxcbbxaxacxbddxdbbaaabaadaacdacdabccbdbbabxxbbbxaxbxxbxcdxxxxcxcxbabbxxdxdbdxbcbccabaabbabbbdabbaaadaaxxdxxxadxcaxbxbxbxbdabxbcdbxdxxdxxadxaaxxaxxaxaaaxxacdaxdxacaaxabcdbdxaacbcdadbbadaabbbaaacbabacbaaadbbbbacaacbadxacdxacaxxxxdbxaaabdbdxxabxadadxxddbxxcdabxxdaaxdxdxdaacxdbdaxaxdbxaxdaxbbaxbxdaxcxacaxbcabaaxxxaacddddababbaadbdaacdaaddbbaadbdabadxdbcdbbxddaxxbdxacbabbbxdacdxaxdbxcbaaxdaaxxaaxdaaxaxacxxxcadbdadaadadaadbdaabdbaaaabcdbdbbadacdaaaabddbdbdbabadaadacaddbdaaacbaacdabcabacaaacdbdaacaxabdxbbadbadaaadabacbbdbadaaxdbbxxxbxbbxxcaaaadxaxaaxxdxaxadadaaaacacdacdabacbdaabadxxbxxxxxaxxbbxdxxbaaxacdxxccdbbacbcdacadbdbbdaacadabaacbdbcdaccababdbdabcdbxdxaxdxbdbadxabcbdbcdabdbdbbaaaxbxbxbaxbcbxaxdbadbxacaabcadadbabdbdabaabaxbaxxbxxbaaabaaaaaadacbdbdadbddxdbdacdabcdbacdaacbdacddacdbccdbdbbaxaabdabbaadaacaabbaddxacxaxaadadbxxcxxxcxaxabxxdaaabbdaadaaaaxacdxaxxbbxxaaaxxbxxadbxdaabbbabcdbdaddbbdbdbbxaaaacdbaxbxaabbxaxxaaxdaaabababbaaabaccbcadbbaxxxxadaxaacbcacbaaabaaababdddbbabababbadacxdxdbxxdxaaaabxaaxbadbbdaabbddbaabcddbaabacacdadbabbcaabbbbacdbbabcdadacadbccdbdacaddaacabaacdbbdabbacaacbaxdxxdbaxacxaacdxcaaaxaaxbxdaxxxaxxacdxcbaaxxdaacdaxcaxaxadacaaxabxababaaxbdxxxdaxxbxcaxxbdxaaxdbxcbdxcdxdaaxdxaxxxaxbabbdbdaccdadbdabadadabaaaaxabdxabdbbxxxaabbdbdbacbddaabadabaaaaxxabacadxxadaadxxxcadaxaadbcaxdxxcdabbcdbdbacbacadbbcbdaabaabccadaaaaaadabbacacbaacacabbaacdadaabcacaddaaaaadbdaxdbdaaaxaxadaxxxdadaadadxcdaxadaxddbdbbabbcbbbaabcaabdbdbabdbcdaaabbaaaaxcxdaxxddacxbbdabbacabbddacdbadbadbaabbcaadbaxbbxbxbadacaaaaaabadabxcxbacxxxcdbccdaxbxbaxxcdxxdaxaxxbxcdadbbaadadbdbadbdbacaxabdbdbdaaaadbcddaadacaxdxaxbaaxabcdabacdbdabaadbadaxbbaxxxaxxxdbcxdacacdacadbabdbaacaabdabacaaaaabxaxxbxacbxbbxaacaxxaaxxxdacdaadbdbdbbdbdbdbabbacabaabdbbdaabdbacdaaacaaccxddxacbacxbdbdaaaabdbcabaaadbaddabbacdbbdaaxcxabaxaxxxdxbbxaxaacbaadbacabdadbacaacbcbadbaacaabdaadacdbcaacdbcdadbdaaaaxbxdxacxxdabcbxxdabxxbxbdxxxxbadabaxxxxdxxaxxabxxddddbcbdbbadbdabacdababxacxbxcdddbcaadbbaadaacbadbaaabaacdadbacddabadacbxaadaaaaxxaxdbddxbxdaaxxxxxacaxabxxbadbbbdaabbcdabaacdababbbadaababddaabbabdaabbbdbbaadbbdbbxxxxaaxdxxdaadxxcxabaaadbdaabaadaadbabccadbacaxbacaabbcdaabdaddabadbaddaaaabcdbddaaacxxdabxadaaxxxaacxxdxaxdxbxxxdaaxbadacbcbdbcbbaabaaacxxxaaaxxxdaxxxbabdbaaaaaaaaaabbabaaadbadbaacdbadbaaaxxbdabcxxbxadxacbdxaadbdaxxbdxdaxxxacaxdbaxxbaaddaaaabdbaaaxxcdaxcdxxxbcdbdacadbbabaaaacbddbcbdbcbabdabaacbdacdxaxxxdadbxbdaabacdbbbaadbadacdacaaacdaadadbaabdadabbdadbxaabbdaaadabbdbdaaabccbbaacaaacaxxadxxdxadxaxxxcdabcdbbabaababdbaacdaccacdbaabdaaadbaacacadbdbacxxdbxxxadxaxacxaxdabbbabaaadbabdbacbadbdaxcdxxxdxdaaxcxxaxabbcacdabadddaabcaacabaabbbbdaaacdbdbacxaaaabdaaxdbxxxaxdaxaaxxadaxxbacbxdxxadbacabcbaaaddbbdbdbabdacdaabdbaccdxxxabxaxaaxaaxabcaxxxxbbxcacbabaacaacadaacdaxxdxaxbabxxabcdbcdbabaaabdabbacadaabaacbaxdacxxbxbcdxxbdbddxxxdbxxbxxbaadaabadxdxxxdabxxxxxdaxadxaadbaaadxxabdxacxdbdbxxacbdaxcxxbxaaacxacxdxaadaxaxadbcxxcdbxxbxacdaaxadabdbddbbacbaddadbadaaadbdbacxbxaxxbdbaxbaxxacxxxbaaxaabcbcbdabadaabaabbdbbbacbdaaaacabdbacdxxadaadbaabbbbbbadbdadaacxxbxaaaxdaaadaabadbbadbdaacaaadbbaddaabdbbaxbcxbxcbbxxxdbxbxdabxaabaadadaaaxdxxaxababdxbxdbxxcbbbcdadadbdaacbdaaadbabacbaacacdxbaxxabdbddacaaaabdabdadacdacaaxbabdxxxbcbbbcddacdaaaccdbadbbbdddxdxcbddaxxxdaabbcbaaaaaacbdacxaxddabxxdadxxacaaaaaaadaacacbdbbadbdbdacdadaadaaacdabcbbdbdaaaxdadxaxxaadabcdadxaxdabdaxabxbddbbxcdbdbxadaaaxxcdxaxacxcbxdbabaaaddbbaddbdaadacaxcxxcxxxxdbacadxcxaaaxbxcxxdxxaaxdxdxdxaxdbxbaacaaaacbaccddacaaxxccdbaaaadadabaabcabbbbdbdddabadabdabaacabbbabcxaadxxbdxbdadacdbdbcbbaaaadbbadbcccdaaaacbbcbcbddaxdaxdaxcxxxaaaxxcxaxdbaxdbxxbdbxxabdbdbddaacdababdbxxxxdaxbdbxacaddaxaabacxxaxxcxbxdbxxcxddaxxdxdxxaaxccxcxxbbaxxabcababaadacddbdabdaaaxxxdbxxcxaaadaacdbxaaaaxaxxadxxxcxaabaaaaababbdxdbabxxaxxbcbxaadxbxacaadxdadbdbaaaaaaacacxxbdbabccbadbbddaaaacdbdaacadaacdaxxbdbccaaabbcbbdaacdaacadabadbadxxxxaxdbcdaaabdbxaabxxxxcxacdbxaxadbaaacbdbaabaacabcdaacbdbdbbddxccaxxxabxxabacccabaadadbbdaabaadbaaacdxcacaadaabdaaaaaaaccbaxxbbbacxxxaxdacaxaaxxcdaaxxxcbbacxxbacxadbbcdbacdbaaaaaadacdacdabacbbdxabxcaxbxxbadaaaaxaacbcdbdaabdbdbaaaabdadadadacabaadbdabddaddacbdababdaaacbadbdaccbaabaccbxabcxdxacdxxaaxcxacdxcxaccxxbxdbxbaxadbacacbxxbdaxxxcaadacaacabcbbcaacabbbdbcacdaxxdxcdxacabxxxxaxxxxbdacxababbbdbabaaddbabdbaadxxaxcbcdbdabdaacdbdbdbbadacddbabbbdbxbdaadaxxxaacxxcdxabaacbaaabdbdadaadadbacbxadbaabxbxaadabaacbbbdababadbdbbddaabdaaacbabaabcdbadaabdadacdaaacbadbacbadaadaacadabcaabbcbdadaaxabxacdadbxbxdxaxaaaaaadabaabddbcbaaadbcddaacdbcbaaadbcadabbcaaacabababacaccdabcbbaaaacdaaccaddbcbddabadaabbdaacbacacdaabdbaaxaxaxdaxcbaaacaaddbdabxaxxbacdbadaxxbdadabaaaccdbaaacbddabaxabxbbbbbxxxbbxdbcxaababxxxxxdbxbxcdxbaxaaxxxxbxabbcccxadbacxdxbdxxadbaxaxaxaaxabdxdxxaaxxcxcbaxabdxxxdxxaxacxdbxaxabxbxbdxcdaxadxadbbxabadbxbbxaxcbxdbxxxdbdbxabxxxaxxxdxxcaddxabbaxabaacabcaacaadadaabbaaacabaxbcxaxaxbxxdaddxcxdadaaccbaaacdabbaaadbaxabcxxbbxxxaaxbadddbdbacadbabacdaaabxxxxxabxbdadbdacccbbabaacbbcbaacaxxxxabxxcbaaxaxxxxadaadxbxxxxxxxcaaxaaaxacbcabbcaacbdaaadaadacbdaaadbxbxacxbabadacddadbdbdaddbadbcbacaadbdxdadaxbcxbdabbddabbabbbcbcbaaacaxdbxxbxdbxxxxdbdddbbxxaacbbbcabdadabcbadaaabbaddbbacdbaccbaabcabdadbbdadaacddbbdaacbdadbaababdaaaaaaacdbcddabcaaabbcaddbdabadddbdadbxxdxbdxdaxbxaaxbxaacxaxxxxbbxxdaxaaxddaadxxxadbbxbxxdadbaabdbbaaabadbacddbaaddadbadadbabdaaaaabcxadxaxcxbcxdxbxxxadbcxaabbcxdxbdaxxxddbdaabadaaadbbbdbdaabadaaaababadacbxaxbxxdbxxaaxxcaxxaaxaxxaxxbxacacaaxcbdbdbdbaaaaadbdadddbaadxadaaaaadbxbxcabcxbbbbbadbaxxaxabdxxbxbacbcdaccdbdbdadaadbaabcbadacbdbacbdaacaacdbxbxxbabaaaaccdabbadaadaaabxaxadxxbbbdxxabadacbaaabdbdbcaccbaabbacaabaxcxaaxxxbaxxxbxxxaxcxxbbaxbxbcbdbaaaacdbaadaaaabdbacdbcacdabdacaadbacadadbdaccbaadxxdxxbxxxdaadacbdaaaabbdaabdaaadbbadbdbbdbcbddbbaxxbdbaaabcaaccdbdbadbdbdadaacaabbaaabaaabbaacdaxxxaaaaacdbdaaadaacbdaaaxdbxaxbxaaxdxaxbdbxxaaxcaadaacccdabaaadbbcdadaccabaddaaadbdaabdbacbdacdacxaaxxxaaaaaaxxxxacdadbbcbbaaabbaadabbbacbddbacabacbacdaacxxxcxaxbbabdbacacdabccabacbdbabacdaaxaacbcxxxxaadaaxdxaxbxxacxbxaxxdadaxxxbdabcxxxabbaacbacbbaabbdaaabaabababadaxbabxxbxxbacaxxaxxxdaxaxcdbxbaxadxacxbxcddbbaaabcbdbcadbdbcdxxcaacacdbbdaaaaabbcabdaxdxxaadbcacdaaacacaabdadacacadacaaaccxdxdaaxaaxxbcdacbaadacdbaaacbaadbacxxxxddabbdadadaddadbaadbdbcdbdadbbbbbdbdbdddbaaadadxdxdacaaxxdxxaacbxaxxaaxxxaaaxdxacbacacdbbbacacdbaaacxxaxcaaaxadbadxcaaaaadxxaxxbaxxaaaabcabdaaacbabdbdaadbadbadacbbccaadbdadbdaaadaaaddbcabdbaaabaaacbdabbaacbbbacbbaabddaacadbdbadacddaaxxacaaxxdbabxxaaxdxxaxaadabdxxxxddxxxxbbbaabdaabbaabadadaccbdaacbbaabbaabaadacadbdbdbbabdaxcxdxxxxaaxxaaaadxdacdacxbdxaaxxaacabdxbxxbxacxdbxxdabxxaaacxdbadxbadbxxxaaadbbaacdadbdadbdbdbbxaxbaxaacadacaabbdaaadaadacbaxaxbxxdbxdxadxbcdaxabaxxdbxxxaxxadbacbaxacxbdaxxdaaxdbbbbxcacxacxcxxxxdxxcxcxadbdbadbcbcaaabbdbddbabaaadacacdbaabcadaacbdbacdbxxdacxaabaabcdaaabcadbaaaaacacabdbdadacbaaaadbxaaxxxxxaxxxadxacaaadaacbacbdaaabaacadbaaaxxaaxbxaxbxaacacxbdaxxabdxcbxbxxbdxaxaadaaaaaaabaaaccbdbcaaxaacadadxxcxcaaaxxaxxxaxdacxaxddaxdbxaacxcxdxdxxcbcxaxxdbdbxcaxdxxcxdxadacacxbbxaaaddaxaxaxbaxbaxadaxxadxbxxbdaaadbxaaxabadxccdaxxxaxbdaxbabbdbaaaaaaacbcaxaabxxabxbxxxdabxdaaxcdxbadxbxxcaxaxbaxccddxxxaaxadbxxaxaaxxbadacacxxxxxbacabbbaacaaaacdaaddbadbdaacdbaacdabacdabaaaaaadaaaxxxbdxxbcbxbxxxdaxaxxxaadxdxxbaxdaxaxcbcaadxbaaxxxdaxadxabxaaacxxxxaaaabdxaadaxxcdxbdbdbaxxabaxxxxcbxbxcxbacddbadbddaaabaaaaxadaxbbxdabdxxbxdbxacaxaxxxabbcdbbdaxacabaadadadaabcbaabadbdaxxbaaaadxxadaxaxbdxaabaacdaadbddbdbdbdbxbxaacaxaddxbxaxxdxaxcaxxxaaxxaxxbbdbxcbababaccaxcbxxxbaadbdbcadbbdaaacaadxxxaxaaabxxxbxaxbdxxdaxxbbcdxxabdaaxbadbacacddbabddbadadddabdbdabdddaaaadadbaadaacaaabaaaxcaxxxbxbxxdxbbccxxxddbaxaacbaxbabxxabxbxbxdbabacbbxxaxbdbdadbbbcdxadacddabaabacbaaccabbdxxxacxbcdaxdxacxcxacxbbdxaxaxxxbxadbdacbddacaadacddaadbcbaadbdbdaaxbaacbdxxcdadbdxaccaaaacacdbdaadbxadaaxadaaaaadbdabdaadbaaacbxdxxaaaaabxxbabdaadaadbaabaabaaaaaaadbacaxcxxaaxaxabxbxddxbxbxxxbbxaxabdxxaxadabadbxdabxdbxxaaxxaacaaadaxxbadaddaxxxacxcaaabbdaadabbbdaacbdbbdxaxdacdxxxbxxaxbaaxbacxadaxxdaaccbdxbcaxaadbcbaabbabacdbdacbcaaaaaacxdxxbbxaaxcdbadaabdabdaabbdabacbacbdbddaccaacdbdbdbdbacdxadxaxbbxxdxbxacaabdbxbdxxbbxadbaxxacxbaxxacaaaxxbxaaxbdaxxxxadxxdxxdaaabaaadacdbxxdbcddadabacaaaaadaadbaadaadbcbbxdadadxdbddaxaacaacbdbcbaacdbaadadaabacaaaaadadaaaaaaaabdabxdxxbaabbaxaxxxxcaxaacbdadadacdbdabdabdadaacacbaadaaacdaddbxbxbcabbdbbdbacdacaabacxaaadaaabcxxxbxaxdadacbdxxbadbadbaaacaacdbacadaaxaaabbdadbdabbabdababbadbacbdbabbadbbaaaxbxbxcxdaccxxaaxxbacxbaxaaxaaaaadbabaabbaaabaaaddaaababddadbaaacdbcbabacbaxbacxcbxaxbaxxcbxxxaxdbdaxxadbxaxbaaxxdbxxdbdadxxdxxxadxbababbccaaxbdaabdacacccbaabbabaxadxxxxxaxaabxabbxdbxbaxaxxbxbaxbbbxaxaabbddabxadbbxcxxaxxaaxaabddaxcabdbaadbacbbaabbbabbccdadadaabdbbdacadaacdbdabdbdaaabddaaabdbabxdacdbdacaacbdabadbdadbdadaxdxxbxbbxxdxxcxabaxbdabacaadadaaadaaacxxaxxbccxxabxcxdxxxbxdxxxdbabbxxxxdxadbaaadbdaabacddabdbcxbxdxaxcdaxxxxaaacabdabdbdbdaacbdaaadbbdacaaabacbadbaaccbdaxaxdbdxcxxaaaddadaacbacabcdbdadbdadbabdadbabdaxcacacbbaaacddababbabxaaxbaxaxxbbbxxdxbxxxxcbdadbaxdaaxabacaacbdaaabdbbcaaabdbdxaabaxxxxadadbaaxxxbxxbdxcaxaaababbdbbaaabdbdabacbaaaabacdbdacbdaaaadddbabcdbdbaadxaaxxxacdxxaaxxaxbaxaccxxxbdxddxcxbbdbaaaabdaaaaabdacabxcdxxcaadaaabaadbbaxadaadaacbbddaaaadbaacbacdacdaacddbabbcdbdaadaaadacdxxxaaadaxabaacbaaaaacacbbbdbdaaadaaxxaxxdbaaxdbddbaddbbdacbaddbbabxbbaxbacaxaaaaddacbdxbaacaaadbababdaaaaacbaxdxacxxxadxxcxxcaaxxcxxxaaadbabbacdadaaacbadbacbbdadbxbxxbbaxaaxxxxabaddbxxxaxcxxbaabddxdaabacdabaaaaadabbcabacdxcabxxbxacdbdaccdxxxdbcdxccxxaaaxxccadadbabaadaaccbbdaaaabxaaxaxxaxaxbbaxadacxxaaxaadxxxxaxxcaaxcbbdxxbxxxaaaddaaacbdaccdbbbcbdbacbaadabccxxcbxaaxxdxaxbaaaxxxdbaxcdbadacbaaadaaaaaabcdbxxbbbdbdadabbbdbaacbaabdbcdaadaddbcbdabacbdaacdbbcbacabaaacbbcxaxabxxxbdbadabxbaabdbbdadbbaacadbbddbaabbdbaacaxxxaxxaccaxdaxxxbaxxaacaxbcdacadxbxbdxabdbdbaadaabdbcbbaaaadadbaaaaaaabdabxxxdbdbadbdbaddaacbbdbdbaabbcbcdabaabadacacaaaacbdaadadaaxbxcdxxxabaababdaaccabbabdxxxdaxbcxddaaddabdbabadacbdabcccbaacaxxxccaaadacacdaddbaaadbdaxbxaxxaxbxabxaaxbaxaaxaxxaaxbxxcxxxaaxcaxxxaxdxxaaxbxdaxbbxbxbxddbxxxaaacxxdxxbxcbadaaadaabdacbabacaaaaaaddabbadaaaadabadbbbbdbdacaaddaaxcxxxdxcbbdbcdaaababadabbdxbaxbadbdadadaaaababadabcaaadbcabcbaaacbadbbdadabbdabdabbaacbdaaaacdxxxaxxbxaxdacbxdxdxxxxaxdaxaxxadbaaaccaadxbbdaacxaxaxadaxxxxxxaaaaaacxxadbxbaxadxdxxadxabbaaxbaabdaxaxxcbabacxdbaxxbaxbdxabxdbdaaaaaaaacbaacbbdacdbxcdaxxxadaxadabcxdxdacaaxxadbdbxbaxxxxbaaxxdaxxbxdadbdxxbaacxacbcxxdbabdabbaacaaaaababadbddaaacbbadabdabdaaaaaaaabadbddbdxxabbabaadbaacbabaacabaxbxxxaadxxabadxxxaaxxcdaaxaddxbdxxdxaxxxadxxxadxdxdacdacdaadabacdbaaaabaacbaaccdacaacddaaabaacaabdbdbacxaxxxxxxcabcbbxaxadacacbxbbaaaaxaaxxxxdbaaacacbadabaabbdbbcbdaxxabaxxxxbdxxdxaxxxaaacccdadaacaabdbdaxxxxxabbdadaaddbddaaaaaabbdbaccaaaacdbbdddbcccaaaxaxxxxbxbxadxadbdbaaaaadbacaaacdacadbbbcdaaxxacdbdbxxbdabbxaxadxdbxxdbxdbbaxdbdxxxxaxbdaacxadxaacbddaxadaaxbxxaccacbdbaaxabxdxxacacbacaaaaaadaaaddbdabcdacbbaabcdbabbdbdaaaabbbxdxxxaabcacdabaaaacbdbbbbcxaxaxcbaacaaaaaababadadadadabcxxbxxabadacxxbxxabxddaxabdxbaaxxxxadabbxdxacxadaxxxbaaxxcxxaxxacxdxaaaxbxacddbdaadaadaabadadxddbdxxbdaxcdxxaxxcbxdxacxdabaxxdxbddaxxccdxdabxxdaadacxxacxbdbxbxxaaxxdaxaaxxxdaaacxbbxadbxxxaaccdbaadacbababdadacbaxxaaaxbxxxacacxbdacxaxbadbdabbxxxcaxxdxadxxdxxcxacdbxaxcaadabbaacbdadaacaabcdbxaxxaxadbxaaaxaabxxxbabxcxxacbaxabadaxxxbcdbaaaaadaaacxcabbaxdaxxcaaxxdxbdxxabdxxbbxaxaxaadbdbdbaacbdbbcdacccbdadxdxaxaxxacdaaaaabdbaaacadadbcaacxdxxadxxxdaxaaabbacdbaabcabbdacdadbdbacbdacbacdbdabdaacaaxacbxaxxababbdbdbaabacbaabaaaaxbbxxdxaadxdacxadxxbaxxxxcbxxcabxxaxdacaddaabaaaaacaaxxacbcaadabdbaaacbcadbadadaacdaacdbddaaaabbbabaadaccxbxxadbbdbaadaaaaaabdbacxbdxaxacxxbacacaabbcadaaaccbdadxxbddbdbbaacbaaaaadbaxaaxdadbdababaacbbddaaddaaabdadbdbdbacbababaabdxcbaxacxxxxdbxacdxaaaaxdaaabdxdxxxaxxdadxbbabbbbacbabdddacadbdabaadabddacdacacbaacbdbbbabdadaaaccbaacbbdabaxxaxaaxxxxaadxxdbdbacbbaaadbbabdacdbacdaaxxdaabaxaabbbdaadbxcaxccxaxdxxxaxbaadbbacdaadaabxcaaaabdbabbxdaxcaaxacdaxbxxadxdabxxaxxaaaddbaaaadbabdaacaadaaabacaaadaaaabcadaabcdacdaabaacabbbdacaadabaadabdaabaacxddaxaxacabaaxdaxbxxaaxadxdxdbxaacaadxddxbdxdxdxbxxxbaxaadbcbcadbaaacdabaccadaaaaadacdacacaabacdbbdbbcbabcdbaaacacdaacbdbdacdbaaaxacdaxdxaaxxcxxbaadbacadbaabdabacdaxxacxxacxbdbdbaxabxdbcxaxadxdacxacacxbxcxdxxaaabadabdbbdbacdbaaacacdabaaxxcacaxxbaaadbbxbxdxbaxxdbaacxaxdbbxbdxxxdxbbdbbabxxxaxxbaxaadxdadbabxbcdbabxaxxdbbaxxcaxbxadxxbbaxaxxaxabdxxadbxbacdaacdadadabbaabaxdxaadxcxxxdbxadaaacacbddabdbdabdaxaaaxbadbxxacaxxbdbdxabaadadbabxdxxaxaaxddxacxxbxaaacbdabaaabdadbacdaacxcxadxaxaacxxxxbxxbaxdabdaabaddbdbabdaaacbxbadabxxxbbbabaadbccaaaaaabccbdadbxbxabxxdbxxadxxdxdxbadxaxbxxxbdaaxxdabdbcaaabddaaacdacbaaadadbaxxxxxadaxxcxdbxadbbcacdabxaxbbadxaabcxdxaaxbxdaacdaadbbdadaabddaacdbabadaadabadadaaaadbccdaaacxxbcxbbxxxxabdacacxdxdxxxxxbxxxabcbabaabdaacaaaxbxxdxadxxdxxxbxaxaabdbdabacaacdbbcadaacbbadabddbdacbbbbdabacccbbdbdbbxbcacbbbbbabbdbdaadaabadbbabxxaddbdxaaacxxcdbxabcxdaabxxbabaddddbdbcbdbdaadaaabaaaacbabdbdxaxxcaxaxddxxcbaabaddbdbccabdaaaaaabdabdacaabdaadaddbacxaxdbaxxxacbcdbdaacbbbcdbbabcdbbadbdabdbdbdaddaabadxbacdxcdbaaccdbabdacaaadbbaccbaaaabcbacbdacdbdacaaacddbaabdadbaabbdbdbdacbdacdbaaacxxxaaddaaaacdaxadbcbxxbcxaabxxadadbcdaabaabcdbcdadbaacccxaabddabaxaxdxadaabdbddbdbabddbbcdbdadxbdbddxaxxacxxadbdabxbacxxbaaxcbdbaaadadddbacbcaccdadabbacdaaabbcdaaxbdacbddxdxcxxbcbxbxcbxcdxxxbaaxdxcxdbcbaxcxaxaadaxbxxacadaxdbcxxxaxxxxbdaxaxaxaaaxabxxbdadbbaacdadaxdbaxxbaxaaxxddxxdbdxaabadbacdbadbabaddbbacxbbxxabcxaxaxbdaxcbaxadaaxxacdaxdababcbabcxbdxdaxxxabbbxadxcadxxcbaxxxxaaacxadaxxcxxaacxxaacxbaaadadaabacdaaaadadaabaxdxxaadbxacxadaxdxddbxdaaacacdbaadadbacbdacaadbdbaxxaxdxxcdxbbbdbaaaaaaadxaxxcxxacxxaaxadbaxxxbdbxdxcbcbdbxxccxacxxdaaaxaaxxdxcxcdbaacaadbcdadbddaccbaxaadxxxbbbaxxcdbcadadaabdabbadbcbcbbaaadaacabababacadbabaaabdaacxddbacbxaxaxdaxxcxaxxbdxcbxaacxbxbxaaaxadaxababbdadadbabdbcdabbdacbxxxbcxadbxxacxxaxxbacxxxabdbddbbdbdbaddabacdbbababxaxxaacdbaababbbdbaaadaadadbcadbdacbdaacbaadaxdaxxddabxbxabxxxxxxdbcdxxxdxadbdbacaacbbbdabdacxbaxxaadbdaacbcbcaaccbdabbdadadadacacadbdbbxxdaaxcabaxaxaxdxaxbcxbacabxbxaaxxaxxdxxcaaxbdbbaaaxxxacadaxaxaxxaxbaxdbxxdbbadaadacbaaabaaaabdbbaaacbabcbadbaaaaaxaxbxbdxxxabxdddxdxdadadacacdbacbdabdbbxdbdxddxdxxxxxxxxcdbxbaxacccxdabbaxxdaxcbdaxxxadaxxabadadbaadbxabadabcbdbacddbacbacxaxxaxdxbaaadaxaaxaadxdxbxadxxdaxxcdaadbacdxbdaaaccdaabadbcdaaaadbbabdaaaaxddaadbbadabdddacaacdaaacacbabbadbaadbbbdbcbbdaaadbdaaadaaacbadbbxacxbxxxaaabbbdaaaaaadbadbdaaaaaadaadacdacdbaadbacaabcabbaaxdacaxxxdbxdbxadbaabbbdbadabbdaaaadxdbdbadbbdbacbbdaaadacdbcaabaadabdaaaxxaaadbxaxbadxxbdbbxxxdaxaxbaxcbxxxdbacbbadbdaadbababdbacdadabbbacaaddaaxxxaxxxaxbaxxbdaabdaaxdaxxxxaxxaadbbdaxxaxaaaxxxabacdxbxxabaxbbabdacacddaaabdbdbadaccaccbdbaacdadacacaabdbbaaaabaacaaacdabdacbdaaaadaddbadaxxababxbbadaacdabadaaacbaacaaxcbbaadbdbdadbdbbcddbaabaacaadbaaabxbxcxxaacaacdaadaaaabdadaxacbxaacxbdbxaxxxbxcxaxdxdxxdxcxbbxxacdbabaaaabababadaaaadadaabddabaaabdbadadacaxabcbabdadbadbdaabcbaadadaababxaxxbaaxxxababdxaxbxbacbacbdaxxxxdaxaxaxbdaxbxabadbacdbabadaacdaadabccaacbacbcddaaadaaabdbcabdbdbxaxabadbdbaacabacaaacdaxxabbabadaaacdabaacacdaababadabaxxccbdbbdacdbcadabadabbabdabadbdbbaaaaabbcdbbaacdabcbaadacabaacdabbacdddbdadbxdbxxxxbbxxaxadxbxdxccbaadbbdbaacbacdaabdaxaxcxbxxcxaaxaacxxxdxxcxbxcxaadaxbbabxbxxaaxaxxcxacxbxxxxccbddadacbadbdbaadaabaaaxaxbxxcdxcxxdbaxxadxxaxdbxxxadxaddaxdxaabbxadadxdbaabcdabxbaxbxbdaxabdbaaxbaadacbacdabdbdabbcdbbbaddbaaxxbbdxaxabaxaaaxxxaxxabdxcaaaxbcdbdacdadacbdacbdbaxxxxxaddbadxddxbbcdxaacdabaaaxxcdaabxbbadxbxdbaxabbadaadbdaadaaaaaaabdabdabaacabddaxxaxxaxabxdxxadbccaaacbbddbacdbcacxxxaxdxxdacaaacbadaadbbdadaaadacadacbdxbaacdaacbabdaaaadbadaaacabdbdbdaaaacxxccxxadxxxbxxbxxxaacxaaccdbabcacadbcdbadabcxaxadxaaxcxbacxcxadbdbadadbadbddbaaxaabxadxxbxadbadbxdadbdaabbdabdaacaaccdaabdaadbdaadbbacbadbacdabbdaabadbbaadbdbaxxdxxaababaabaabaaadadbdbdbcbaabdbabababxcaxxadbxxaxdxabacdxxxaxxbxbaxcdacadacdaacdbbdaacaabdaaaaadbddabcaacaaaadbdacdbcaabbacbcdbaacbbbxxaxaaxaxdaxaccdaadaacdaaaaaabbxaxadbadbcdaaabdbbdbabdbcxxdaxdxabdxxdbadxaaaacxxdxxacbabdababadbabdbbabdadbbdaaadacxxxbdxaxacxaaxxdxbbbxaaxaxxxxdaabdxxaadaxxcxcbbaabbdbaaaaccbaabcbbbdxxbaxbaxxadacccdabaabadbaccabxxaaxcbcbxbaacbcabcdacadabbbdbccdbdxdbxxadxbcbdxcdbacdabdbbdbaaacabdaacdaacbdabaadaxaaxcxdbcaaxdaxdxcxxxbbdaaabaxaaaxdxaaxxxbxaaaadaxxaabxxxaxcdacaxaxaabbbbaxaxaxbdxaaxdxxaxxaaccaacxxxdaxbdxaxacaxaacxabxbdxbaxxbxxbdbbcaacacaadacbadbacadbabaadacbbabaaabdacbaaaaaabddbxxdxaxdaaxaaxbxdbxcdacxadadaxxaxxxabdbxacbdbdaaacdbbdadaaacbcxaabdaaadbxxxaaacbbabcbaacdbacabaabaxdbddadxaaxcxcxacdabxxbxaxbbbxxbdbdaaxcadadxdxabxcdaaxxaccxcxabxdxbbaxxdxaaxbbdacdaaabdabdbaaadxxacdabdaadbbadabccbaadadbdbxdxabaaacxaacdacadbdbdbacacdbdaadbdaadaxxxcdxbadadacdaaaddadbbxabaabxacacbaxxaxxaxaddaxdbxxcxxdbxbbxxadxdbbcxdaxxbxxaxxxdbxdxbxcdbabxxababdaaxabdaxxbaaaadacdaaaacacbdbbbdaaaaadadbcdabbxbbxadabaadadddbdaacdbaabdxxadaaxxaaxbxxaadxaaxacbxdxaxabaxxxcxxaccbdbxacacxcxaxxbaaabcbdacbcbbbdacaacdabddabaabcaacdbccxxdaxxxbxacxbcxbbdxabcxadaaxdbdacbdbxbxabxxacbbacdabaaaadaacaadbxaaxadbxxcxdaccbdxccxxxdxxaxxddbaaadabaadaacaaaaadbaabcdabaabcacbbdbdadacaaadbdaaxxacdxaxacdaxxxxxdxaaxbbbxaaadbdbaxxbdxadbxxxxxxaccdacabdxaxcddxxdaaxdxbcacaabaacdaaacxcxcxcdxaaxdxxabddxxxcaaaxdbbdaaacdbadaaccbaaddadbaxbdxabxacxxdxaxaxadadbcadacababbacabcdddbacbacabdaxaxaxdabxaxxcxbcbxbxadxadaadbdacxbcacaadbcaaacbbdbcaaaaaxaaxxdbbdxxaabaaccdbadbabcacbacbbdbabaxxbdxxaabaxdxxdacacaxxdabaacaadaaaaaacbadacxxacxxacbabxdabdbbadbbdadbaaaabcacdbabaabbbbbacdacdadaaacbaacdbaacbdbdaaaaaadbdaaaaaaababadaxxbbaxxxdaxabaxabacaaaadbdaddabacbababxxcxxdaacdxaxdaabxxxbxbdxxxbxxcbxacdxaxaxbacdaaddbbcddabbdbaabacxbacxcxxdabdxaacaxxxxaxbxxcdacacabdaaaadacacbbdabdbaaaadbacbaaacccaacdxabcdaxxaaabaxbxdbxacxaaxcdbxxxbdbaabcbbdadabbabbddxcxxaacbcbacdacddaabadbdaadbbadadbbxaxxcacccdbaaccbbcacabdaabaadbacaxaxbaccdaxbaaxdddabxxaxxxxaxaaxacbbxcbaxcbdadbacacaaacdadadbdaxxxxxxxabacdbaaxadxaaxbabxcaxxaaacaaabacacadaaadaadaxxbdaaaadabaacdacaadaddaaacbdadbcadbdbbadbbaaacbabdbaaacdbaaadxacbxxcdddbacababdaaabaadbdaaadaacdaacabdxaaaacaacdabdadbacbaaacaaabaxxaxabxdbdababbxxaxabdxbdxaaaabaadbdabbbabcdaadbbcdadaaaaxxdxxdbdxaxxxxcxadaddacbdbdbdabaadbbdxaxcbaacdbdabacacacdbacaaaacxaxdacabbdaabaaacdacacdaadbbxdaxxbbabcaaaacdaccadbabadbbbaadaadxxxxaxxacbcbdbdabdddbbbabbaaabbccbdbdadacaadacbaaabacbdbdbaadacddadaacaadaabbcaxdbdaxbxxaxbaaadbbbbadaabbcdbdacbddadbxddxadadabdaaaxcxxaxcdxdaabaaadaababaaaabaaacbbbaaaabbdxaxxcaaxxbxdbabbbaabcbdbcbaddbabaadacbdacabacabbbacdbdaaacxaxxxadaxxacbbxaadaaxdaabxxaxxdxaaababadabaadbaadbbaacaaaaaxxxaxbxbadbxadabdaabaccdabdbdbadbaadbbabdbdaaaacdadbadbabaabxaxacdbbxxxxxdabxbadxabcabxxxaxxxbxaaaacdacabadbdbbacadaaddabxbxxaaxxdxxxaxdacdaxaxxbbxaxaaaxbxdxbxxaaxaxxxbaxcxabaabaxacxaxaacbxaaxxbxbadaxxxaxxddbcdabbabbbabacaccaaddaabbacbxxbddbxbdxaaxxaxxxxdbaxdxcxxaabxxadaxbaxaxcxbxxdbxdaacxbaccaabdbabbadbbabdaaabacdaddbdacaaacdbbdbaabddacbdbdabdaababaadacadaddbdbbabbabaaacxxdbxabdxaaaaxxabaxxxxaaxdxaaxaxxabxcxbxxxdbacxxdababaxxbdbdbxxabdbdbxxaxbdxabaabbxdbdbxaacxbaaaxxbxacbaxxdxxdxaxbcxxadbdbbbaadbdbaaaabbdbbxxxxbaxbbbxxbxdxddabxaxxxdaxabdxxaxabddbadxxdaadaxxdxbbxdxxxaxabbaaaaaxxxbxbxbaxcaxdbxxbdbxaaxxdxxabxaccdxxcbxxdbaxbxxacaaaaaaaabaadbaxbbxxdbxbcbdbdaadaabddaacbaadbacabdxxcdbdacbdbdaaaabacaacbaaabaaaxaxdacdbbxxdxcdbaxdbxaxaabaxcadxccbaacacbadbdbbacaacdbbabaddxxbabaxxxaxdxbaabbxbxaxbxxxadadbdxxaaxbdxxxxbadacbdacaaaadacaacabdbabdabadaacbaaddaacaacabdbababdbbdabdaccaaadaxxaxxxcxbdbdbadbbdabdbbaabdbaaadadaadddbdbbacdbadacbbxdaaaabddabdaaxxaadxdadxacbxxxbacdababcabdacbaaadbbbabababcdacddbbaadbccdacbaadacabbadbabadxbaxaxaaaxxcxbaaacbaaacddabaacadabacbdaabaaadbacxxbdxxaxaxaxxxcxdaaaaxaxdbcxxadxaacbbcbbbbbdacaaadadbdddbaaabdbacdacacaaacbbbbdbadbaadaacccdxcdaadadbcbabbdbadabdaadaaadbdbaadbdbbdbbccbcbdabaacbaabdabadacdaaaaaabadbabdacabaaaaaaacadabbaxdaaaxbxdbbcxbbdxbdbaaxxaadbbcdaxxdbxbbdxxdxcxbxacbxaaxcacbddadbadaaaaaaabadaaabadbbdbcdaxxaxaabbadabdbdaabddaaadbcaxabacadaabdabxxxcbbxaaxaabbdbxbxadbaddxaxabaabdxxcdxxxaxxbadxbxaxbacxdxaabxbaadaaccbdacbbbbadbacdbcadbxadxdaxbaxdbdbbxxxdxabdaaaabbbcadaaacddbbdbbdbabdaacdbdacbcaaaaabcaabdaaaxaaaaxxxxxcdbdaxaabbxbcbxxdbabacbcdacbbdabaaaaddabaddbbdbdacabbadabbdbbbdaccbdddadacdaddadaadabaacbbadbaaaadaaxcdabxxxxxxbxbaxdxdacbxdaxdxxdxdbabaaddabaabdacdadaaddbdbdaabcdbaabacbaacbdadbaaacacbaaaddadabdbdaccbdacaabdbabbxdaxdbaxxaxxadbcabdbbacdbbdbcbaxbdaaabdaxaddbadxxxxbxaaxxdbaddadbaacbbacadbaxcxxccbxaxbdxcabcdadbbaaxbxxxcadaddabdbaabadadaaabaxxxddxcbabcddbddbbdbaaaaadadaaabbaabbaaxaxdxdadaaxxxbxbdxadaxbbddbdaxdaabxadaxbdaadxaxaxcadbbbbaaaaacbaabaccacbaacbcdbcdbdabaxaxbbbabbxbaxaxcxdbdaxaxbcdxacdxcxadxxaaxxxaaxxdacadbdbbbbbdacbcbbbdbdaxxbxxbabbdacdacbabcddbabacbdbdbbdaacdbbdacdbbabbaabadadbadaaaabaacbbaaaaabdbadbcbdbdaddxxaxcxxbxbdbbdbcbdaaadbabbadaxaaxxxaxxdxdaxxacdxxcadaxxxaaxbxcxxaabdaacdbacbcabdbdaadaabbabaadabbaaadxabxxxbaxbaaaxabddbdabcacacabdadabddacbxaxxxbxxadbaxaabbbxxbdxxcdxbbdxddbacdabbaaaadbdadbdbaabdaaaaadbabcbababcbbdaaaabaacxxxbbaxaaabbacbdaaacbaaaabdbdbaaaabbacbaacddacbdaadaadbaacdbdbaadbabacadadbcadabbaddbcddbdbdadacxaxaxaabxacaxxdbabadbbacdaaaabdaaabdacaadadbdbxaxxdxaxbdacxxaxaxxxdbxxxdaadadaabacaadaaabadbaabbabacbabdbacdadbdbccaacbdaadbdacbadbcxaadxxaxxxdxaaxaxdbabxxadxaxdadxxdxxbdaxaaxaaxxxxbaadxxbdbxxxxxacxaaacccbaxaxdbbaacabbxxdxcxxadadbacaacddbbdaabdbaxbaabxcabaxbxbxxbxbdxbxxaaxxxabxaaaddbdbaddbabdbbaxxaxxdacbdbaacbacbdbdaaabacbdbabaadaxxabdxxaxcxbaadbdbadadaaaaabdbbaadbacdaxcaaaxxxxcbxabaaaaxbxxdxxxbxxxcxxbdbccbdbxxccxbxaabdaaadbccbabbadaccxxdxbbaxaxaacdbaadbaadacbddaaaadacdaxxxaadxbxxcxabaadaxaxxbxbadaacdacadabdbacaadaacxxdxdaxxxxaaxxxadxacxaaxdaabxbadacbaxbxcbxbcaaxacacacbabdbdbbaccbcaccacaadacdabbaaacdaabdaccxaxbdadbbcdbdaadbaaaacabaaccddabdaddacddbacdadabaddaacbcxxbbdaxadxadxaaxdaxbxbxbbxxaaxxxxxaxdbxadbxxbaxaaaaxdabaaccaaabaabdbbadbdaaaaabaadxdbxdbbxxxbxaxxadxaxbadxbxacbbbdaababbdaaaaaxbdaxaxaxaxxacxxadxadxbbxxbbaacabaabxdaxxbdbxbxadaaxxxdabxaxdxxaxxbdxbdxaadaxbbdaaxxxaaxcxbxxdbdaaxdaxbdbbadbbbdaadabbbdbdbbadaadadbcbdabcdbacxxacaabaxbxxacxbabaccxabacacxxabaaxxbaaaaadxdaxbaacdabdbxaacdxdbdabaaxacaxaaxcaaxabbxadxcaaxdxdxxxaxbaaxxbdaxdbxbdbaaacacaaaacaaacxcdxdxdbaxbaaxaccdbadadaabdbdbadabdbdbbbadbcaadadbdxxxxxcbdxaddaccbcdbcaabcbaaxbcxacxxxxbdabdaacadadddaaddbbbdbxcdaacaaaabbdbabaaddbbdabbaaxbacabbadadabdbababdbbbaaababdabaadbaacdaadbacbadaacdacdaabdbaaaacaacaadacddadbbbaacbbdxcxdbxxxcdbcxcxxxxxxxdxbbdxaaxxxddxcbaaacdaaaaaaxaaxdxbxxxxcxbbaaaadacaadbdacacbccxaaabdbdadbabcbbacacdbdxxacdxbxxxbxcbbabxxabxaaxxaabxbxbbxcxbaacddadbdacacadabaaadbacdbdxcxadxaaaaabaaacacadbdbaabacxaxaxxxxxcddabaaxaxxxxccbdacaaadbdacdaccaacddbxadbxxxxdaabdxdbdbabdadacbddbbaadaabaacacadaadbbccbcdbaababbacddbdabaadaadacbbadbdbbaccdbacabaabacdadabadbaabbaccadbabxxcbbxxxxadaaabadbabaaadadadbdacxxxaxaxaxaxxbdxaaabaxcxbbbbxaxxxbxaxcxaadddxxxabxaaaaaadaaabaacdabbcbbbabdaabbdxxxdddxadbdbabbbdaabdaadaaaaaacadaxcbaxxcadacadxdbcxbbdbxxxdbdbaxcaacaccbaabdbbbabbbacbabaaadxxdbcxbxbabaaddxdxaccaaaaaccbdadbaddbababdaaaacbdbaaacaacaaaaccbdacacdaadbxbaacbacaaaaabcbaaacdbacadxxaxabcacaadadbdababaacabbabdxaxccxdxxxacbdadbbadaaadaadbaddbaadbdacbdbcbbxxdbxaxdxaxbcxxdbaaabxxxxxxxdabaxxcbaxxdbxbcaaxbxadbxaxcbbacbdbdabadbaadbaxdbxxcacaxxdxxdabadadadadacccaaaadaabcacbaaabdacxdxxxdxdbxdxdbadaccabcbaabdbdbbdbaaccccaxxxaaxxxcxacbxxcadxbdxcaxcdbxaaacbaacabbaxdadabbxxbxxbacxacdacdaxxxbxaabacbaacadbdaaaaadaxxdxaaxcdbxxxxxaacaaaaababdbdaaacadacacbdadxxbcxbxxaxdbxxxbxabddabaaabacaaaaabdaaaaababdbabcbacxxaaaxxdaxxdadaabcdbabdabdaaaaabdbdbaxdbxaxcbbadbxxbxdbbxaxaxaxxabdbbdxbxaxbbcdxxxbxaacacxccxdadbdadaabbdabdacbdbxcbbaaaaaadbbacbabdaadxbcdabaaxbacxaxdbxbacaxacaaabbbaaadxxxaxxadxcbadaabxaxabaaxaxdabaaaaacbaadaaacbaaaxxxxxacdbddabcaacdbababbbbdbabaadxxxxdxcbxxaaaadbbdxxxxaabacbbbbbdaxababcdbbacccdabbdbaacdaacbbdaacaababddbacdaaadbbcbacbdadbaacdaabaadaacbbadbaaacdbabdacdbdabdbcdxxadabdbcxaxxbbxbadxxxabaaxbadbdacbdadaccaabbdacaadxxxaddaaabdabdadbcdbbdxxxbxxdaadbabaaxxdxabbaaxaxbcdxxxxxdbdbbdabddadbdadaaadabdbabdadadxadxcxaaaxdaxdabaaxbaxxadxdxcdxcdxdaaxxacdacbabxbxaxxxxxbxacdbcxxxcabaadbbaadabaaacccaadbxdbcdbxxcdbaaaabdadabbaacaacacdabdadbxxbbdxxaxxbdxcdxxxbxbxddxaxxxabxddxbxaaabxaaxxxabxaxxxxaxdxdxbxddaacxbxdbdadaxbxxxddbbaxdbbdaabdbbaddabaaaadbacabdaaaabdbcbdxcdadaxxacxxdbbxadadxxccdbxxdaabdbbadbdbdbaadaadbbabaccbababababacdbcbbaxddabbbxaxaxdbxaaaacdbaaacdbxaxaxbxabxbbxxcxxbaaaxxxaacbxaxxaaxacdacdbacbcabaacbabdabadabbaadbdbdxaxbdbdbaadbbadadbaacdaccdbdxaaxaxbxxaxbbbdadbcdbddaadacdbxdxdxxaxbdxxdxxdxcxxdbaxbbaxdaxbxbdbxbxbxdxxdabxbdbdaxaaaacaxabxbaxdxxxcdaaaadacbcbdbdbdbabaabbabbdbdbcaaaaadbbdaaaadabaacadadbdbdbxabaddbaaaabdbcdaabbcacacacaaxdbbbxbxaxbxdaxxaxxxacadbacadaacbdbcaaabdadacbbdbbacabcbcbacdbdbbcdbaadabxdxbacdbxxxdxaxcabaaaaaaaadaabbdxdxaxbdxcaaxxdbxcdbdbdaaacacdxdaxabxacxaaaaaxabdbdbdacddbadabdadbaaaacbaaacxaxxxxxabbdaaxbacdbxxbxabaacbabdaadaabddaacdaxxdaxxaaxcxaccbaacccdadbdbaddbbdadaabcbdaaxxadbabbcbxbbdadbdadbaaaadbadbxxxaxxdbcacbcddacaaaaacaabdaadadaadadbdbdbaacbdbdaaabacaxadaxxcbddbdbaaababbacdacdabadaacdbdaacdabacbdbaaaccdbbxdaxcxxaaxaaxdbabxxdaaxxdbxxxbacaaaabacdbdbcabdadbbcxacxcbcxxxxxadxxaxbabacbdbaxaxxbadbxxdacaacaaxbaabaadaabdaddbdababdaaddaxabbxbxxbxxxdxcdbaxxaxdbbcbabacdacaaaadaaacdbbaxaxxaxxbxaaxxcdxbdaaaxcxxacxadabxdbdaadbddaxdacaccabdacabaaadaxxxdxxxxbabacadaaddbdbadaabcbadbaaacaadbadacaxaabbxxxxbaaxxabxdbdbaxdxxxxadxcxabxxxbdbcxabxaaxbbaababdabdaaddadbadadaaccadbxxbxdxbbbadadbaxbdxdddbaxbadbdabcaaabddabdaaccbdaadbbaadbacaabaabbxxbabacdbabaabbdbdadbdadadabaadacxxbxxxdabbdaxdxbcbcaaxaabbadbdxxxdxabadaxcxxbacbxbbbxdxcaxdxacacdabdaacbaababbacdacacxaaxxacbdaadaacdacbbdbbddadabbbababaaccaadaadbxxabxaxxabaxdxbxdxcaxcacxxbxaxxacbxxxbdaxbddxcaaxabxcbxbdaxacxddbaxbaacxbabbdabbadabbabaaacaxdxbadbdabaaadbdaaaadabcacdbadbdbcaddaacacaacdabdbcdaaabdaabaaaxbabxxbxbxxabaxxacddxxbccbaddabdbxxdxaaaaabdacbaacxdaxdaaccbbbdbabbbddaadbdaaacabxddbdbdabaabdddacaababdxxbdxbdaaccaaadbxxdaadxdbxcdddbaacdbaxxxbxdaaxaxcxdbaxdaadaxaabxxdxaddxbxxaxxxbcxdaxxxbdaxcdxacdbdaaadadbddbdbabdbabaaadbadabdbacaabbccddbcddaadaaabacdaaxbxxaxdxxabadbcbxxaxdadxxxbxaaxxbbaaaxaxabdbbaadbaaaacadddbcbaaaadacacdbaacdbabaxdbadxadaxdbxxdaxxaxaxxcaxadxaacxdxxaaxxxxdxbbadacbaaaadacaddbacbdaaaadabbxbdabaxdxacbbxdaadaaacbaaacaababdaacbaaadbdadaaaabaadacbacdxcdxacaaaaacxcbdxaxxaaaaacbdbdbaacbadbadaacxxxacxacdbxbcbabxxxxadbxbbbxcccadabacdadabacbacbbaaxcbxaxxxcdbdbdbxxxdacaaaddacbddaccabdaadbaxxaxaxcxxxxaabdbdaaabdaacabadbabdbabbacdaabbxaxxxbaxxaacxbxaxbdaaxddxabxbdxxxddxxddadaaccdadaaadbdaxdbxddbdxbxxacxbaxdaaaxdxadaacbbadbbacadacdadbdaxxdxabxcxaxbaxbaxxbcbdadbaabdbdbdabdbaaadxxxxxadxxdbaxxxxcxbxabbcbcdadaabcbbabbadbdabaacdaaadbadbbccbadbxdbaadaadadaabdbbcaaddadbbaaabdabadadbdaaaaacabbbdbadbcdaabbbaadbbxcxdbcdbbcbxacaacabbaabbacdbddacbaaaabdacddadaaaaaaabdacdbbcdxbxabbbaaabdaaccaadbbdaacdbxaabccdxxaabaaaxbcxbbdbxxabdadabaabdbaadadbaddadabdaadbaacbabcdbcbacacddbddbbdadaabcaaxaxxaxadbccbcabxcxxxdxddxcxdbxxaaxxxxdxxaacxxxacbaxxcbaaaxadxbxbxabxxaxxbdxxaaabxacxxxdxaxbdaabaaaaaadbdabdbadadbabxxaxxxxxdxdxxbdxdbbadaxdaaabaaxbdxcxaabxaxaxacbdabaabcaaacadaaaaaadbacxbxxadxcxbdbdxxdaxxdadaaxdxbadaxcbbaaxxaxxxdxxdxaaxbabxxxbbxddxxxdbxadxbdbaxxxdxxcbdaxxbxxbdxaaxdaaaadbdbadabacbccbaadaacdxcxxbaddaddbdbdaaaaccdaddaaxbbbxaxxbbcbdxabdaadbadbaababbaadacaabaxadxcaadacdbxadxcxdxcaxxxadbxdbxxxaxxdbaxdbxaxbdxbbdacbcdbdxxbdxaxdxaxbdxaaadxxxaxdxxcbxdaxcdxadbxxaaabxxaxbbxdddxxaxxxdaadbxxbdxaaaacaaadaxaddaabdbdbababadadaacbaaxxaxdacdaadbcadaacbdabdabaaxcabdbxxdbacabaaabdacbabadbbbdaacbdbbaacacaaaxacaaacbdababaaacaaadaxxaaaxxaxdxaddaxaxxcdaxdxxacdaacxdbabdaaaadbccdabaacacdbaaxxbbaadaaacabxxdbacbbabdbbbaaabbbacbddadacdbbdaacabbdxdaccxcdxxaxbcbdbabbdacdaadaadacbaaacdbdaaabxxadxabxacbbaccaaacdacbdaaabccadadaacaxxxcadxabaxxaxcxbbdbxxdxdbxxdxabxxbdaaxbxaaxaxcxaaxxacaxacaaacbdabaaaabaaaacaaacbaadaddbbxxbxacdbxxaxcaadaadbdbddbbaabaaababbdaaabxxxbxxxcaaxbxcabaccxxaxxdbbdxxxdbxbxbaaxacbbbaxxxbxbbbaaacaaadaabaxxaxbabdadadaadaabababdbdabacacbdacxdbxaabxbxdxaaaxxxdadbcxbbbxxxxxxaaxxbcaxddaxaxdxxbaxcxaxccxxxxxxccadaadaccdaaaaacabccbdbbcxxbxaaabdbcbdadaacbacabaaadaaccaadxcbdbxaabxdxxdxadbxbbadbacbaaacddbddacddbbdabdbbbdbdaxbxabdabxbadxabaaxxdacdbcadxaxbxbaxaxxdxaxxcxacacxaaxdxxdadabxaxaxaabbdbadbbaaaabcbbdaxxxbaaxaaadaccacabaaadbabacdabcaxbxddbaxaadxxxaaxbcbxacadabdxxcdbdaaaaacbdaadbaacbaccaaacbbcbbacbaaxbdxaxacxacbaacdbcbbdbaaacadbacbbdabbdbdbadbacabdxxxxxxxdaxabbbxxaxaaccaxadbdxdbacaccbbbcdaddaacacbccdabdaabbdacccbdacbdbaxdaxdxbxxxcbdbxdxdbadaaxaaxbxxbxbdaabxcxxxabbabxaxbxxaaxxaxaadaxaxaaabdacbdaabaabdbabcdbdbbbabdacdbabdaaaaaabdacbdbbbaabbabacabdaacaaadaxdbaxbxaabbadxbxaadxaacxaxaadxaabbxdxxaxxbxacdbdbadxbxdxadaxxbxxaxxxbxcxxxdabbaaccbxdxbabxxbaxxcdxxacxadxddxaxabdabxcxbaxxbxxxxcxaacacdaacddaaaadaaaccdxcbccaaaxxxaxxxxbbdxxbxbabcbbxbxxxaadxbbbxbbdadbdbaadbdaaadadaadacabaaacadbdbdbaabaccabaabdbbxaaxbxdacdabxcxxdbxadaaaxaxabacxxdbbxaxaaaccdabdaabdaaacbbdbaddaababbbcbdaxaxdxaxxcxxxxbdxbacaaacbxcbxbdxxxaaxbxbaxaaaxbdbaxbxcbbxxxbaaxxaxxaxdaaadbbaxxabxacxdaxcxbdbbacabdbaaacbaabacbacaabbcxxxbxbxxcaxxaxbdxbxacxbdxbdaxaxadxxcdxxacdxaxxbdbxxcdbaxxxbbdaxaxaabxaxaacdabacbcdaaaaaaaaaacadacxbdxxxdxxxxaxxacxaxdxaaaabdxxaxcbxadxxxaxaxabxaaaxaaacbaabdacaaaabdabbdbadbddbadaacaaaadbaabbdabaaaadbaacabdbdaxxcbaddxxxxxadbxacxdxbxbdbaxxdacxxxxxabdxcaxxdxdacxaxxxbaaxxcaaabxxxacdbaxaaxbadxxcaabdbdbbcacacdaaaabaacbxaaxdxdaxxxaaaxdadbaaaacddaccaacdaaadbbbdbbaabbaaacbcccdadadxxxbbdbxcxxxdxadaxxabaacaaacacadbdadaabcdaxxxxadaadabbdbcacabaabdadaacbxadaaabbadabcaaadacbcadxdxdaxaacxcxbxxcaxxaaadabxbxxaaacaaaadaccacaaaaacaadbaaabaababaacddabdaccdadbaabaaabaabaacdbbdaaaacbaacdacaabaddbadacdbbddadbdbaaxaaaabacdbxbbadaacbaaadaabdadbdadbacbdacxaxbxxxbxaxxadabbcdaabdacaccbabdaaaadaaaxaxxaxdaxdxdbxccddxaxxxcbdxbaxxxaddbxxxxxdabddbxxbcbaaaaaaadabbbabaabdbcbdbaaacdbxbaxaaxaxxdxbcxxxxadxbxxdabdaxaaadbxdbdxxaxdxaxbdaxdbxdxbbbxdxaxcaacaaaabdadbdaaaacbbcdadadadbaabbbbdaabdbbbdaabbdadacbbdbddbaaadaaaabababdbcbxcbaadbcxabxbdadbaaacaxxdbaxbxaxxbaddxxbxcaxxxaaxxaaxcxaxxxcababdabbbacdaaaabacaabdaaaacdbbadbaacbcdbccdbaxxacacaabxxddbaaddxxadxxxxxxbxadbbxbxadxxdbaxxxaxxxdadbxadxbadbdabaaaacbbaaadacdadaabcdbadacacdaadbdbxbacxxxdxxxxxaaababaaaxacxaadbacaxxabxaxbaxxbdbxaxxcbaaabdbbxaxbaacbxabbaaaaacaddbdbaaaacdbcdaacbdbacbaaabbaaadbabcacdbaabdbxaaaxbbxbaxaabadaxaaxxbxbxdxxdaaxdxxdacxxxaxxbxaddxxacacaaabbadabdbbdbaaaacxaaaacbbaxxxcabaxdxxaadbabccacdbabdaacddacaacxxccdababbdbaxxcbacababaabdbdaddbadbaaadadbcaadaabdbxbaxaxxxxdxxxcdxxxcbbaxxdaxxdxxdxxcdabcbadaaacddbbbdbabbaadbbdbcbaabadaabadaaaadbaaabbdaaadbdaabcbbaddaddadaccbbdadadadbbaabdbccdbxaadbadabaacxbaxaxxxxbxxaacbdadbacabdbbbbaaadabbbxacaxbaxbxaxxcxaaxbaaxabxxxbxxadxadbxxbxbbbaababcaaacbcacdadbxbadbdbabdbadadacbbaadbacdaaacxacdacdaxxxxdbbacabacaaaaaababdxdbxaxxabxxddadaxaadabxxacbxbxbbaxdbxxcxxxcaacdaaabaabcbcbaadbbaxdbdxdabaacaaaabbabbabaxacdbxaxaadxaaaccaaxbcbabcdaaabdbbcbdaaadbadaaaadbadaaxxbdxdbxxxaxaaxaxaxccxdxbdxxbcabxaadxaaabxxaabdbxxxcxbxaxddacacaddbdaadbabadbaxaaaxxacacxxxabbabcxbxxadxbaxaccxbaaacxxdxaxdxcaxbaaxxaxabaxdxxdbxdbaxdbcbaaabdadbadbacabbdaadbdaacaxxbxdacadabaaabdbaaacacdbbdaaaaabacdxxxbxbbaxxcacdbaaaaccbddadbbdaacbbaabbdacdbdbaddaxxbxxdaxaxxbxxaaabdbdbdaaadaaabacaaaaaaddxxaxdxdbcxxxaxxbaxxxaaxxacbaacbdbbabaaacdbdaaadaccacbabaaacabxbdxacbbxdxxxbaaabaaaaabadadaxdxxaxaxxdxaaxbxaxbxdaxxcdbxxdxxxaaxbxabdxdbcxdxdadbacdbdaadabdaaacaacbaababbcbbxdbbbdaxxbaxxxdbbdxdxxaadxxdabaaaadxaacaxxcaxaabbxdabaaabaaccaaccdbcaaxacaaabdacbbaacdabdaaabbxxddxxxxbadxbadaxaddaaadbbdaadabbaacdbdabdaaxcaaxaxxxaaxaadxaxdbaxxaaxxcbbbxdxcbxdbcaabdadbdbaabdaccbacbdbbaccbcxacbbaaadadbabbdaaadaadaaadbcxcbcacaababbdbaaaaaaabdbadxxadaadadbaaabdbdaabccdbdbdbcadbbcbdbbadaaadabdaxxcxbaxbbaxaxxbaxxaabaddxxbbaabxbxcdbbbdbbcbbaaabaaacbbadbdxbbdaxxacdabaxbabxxabdbdaabxbbdxxxxbaaddbaadbaddaaaacccadadaacaaadxdxxbbaadaaaaxxxxxdxxaxdbabadaadbaacaacdaaababbbbabdaxacxdxacdxaaaaxdxxxdbdabxxabbacbdaaaaabbaabdaabdbcbacdaabaabcbaaaaabaadaabcbddxxxxdadbaabbdbaaaabacdbbaabcdbaaabadaabdbdbcxaaxdbadabaxabbbdbadbdbadaadbadacaxcxaaxddxxbxaxcxbxbadxxbcdaacxxxxxbxxdaaxacdaxbbxcacbbaxxbxcxbbdxdaccxbaabaaxbabcbcbdbacaddbaadacbbdbbaabbabdacaxbdbcxdacaxxxbdacdxccaxxbdbdxxxdxabdaxxxxbaadxcxbaabxxxacxaxxadabaaabacxbaxaaacdaaaacdaadadaabdbcxxbacxxxxxdxcacxcaabbdbacxcxdabdxbxbxaxxadxxxxacbbadxdxxxxdbdaxxaaaxxxxdbxbbaxcdbcdxaadaaacbbadabdbdbaaadacbdbxcdxbacdbdaaaaaadaaabcdbxdaxxbacaxbbdbabadaccdacxxxbbddbbbbbdbbaadaaaaacddacdbbcdxbxxaaxaxcbaaacbaaabdbabdbdbdxadacaxxaaxcdaaacbadabdaabaadbadbbbabdaaadaxbxxxxdxxadbdbdacdabdbdbdabcacdabdadbacddbadabaddadabaaaaddacadabacaadacdaddaadbdacbabbxxxxxbdbdbcdxxxabxxbcxxxbxdaaadabdbdadbaaaccdbxacdadbxaaxaaxxxxbxaacxcxxxbbxaacxaacxxxaaxaaxxxcbxbaxabaacdbddabaabacbaaadbaacabbcbdbacaacabdbbdabacbabddacdbbbxadaaabdacdaadbadbaabdbaabadaacbcdbadbddadabdacdxacbdbbaxdxaxbbaaabxdbadaaddxbxaxabdadxaxbdxcbaaacacbcdbabccdbbbdbadxdadadxxxxadadxxcacaacdaaaabcaacdadbabbaxbacbcdadacbdacaabaaaaabaadbbaabaabdxabxaxaxbcadadaaabbaaaccbbdbadbabbxbabxdxdxdbabdxxdabbdaxbabbdbadadbdaaccaaxdxaxdxaaaacdbcxcadbabbaaxxdbdxxcbaabdaaxdbbcxxbdbxaxaxbxxdaaaxxxbdxaxcdaxxbxaaaaadaxbaxaacdabxdbabcbaababddbaaaabacadaddbaxxbbaxcabdxdxbxbaxxxxaxxadbxdbxdabxxxxdbdbadbbabdadbdadaadaaaacdbabbbbdbabaaacbadbdaabdbddbdbabdadaaaacxdbadacdabbdaaadbdaababaacbbacdxxbadbxacxabbbbxaaxabadadddbdacbabdbdacdacaaaaaacbacbacabbacaaaabacbdabdaddaadxxdxcxaaxaxddbaxxcxbdxdbxbxdbaaabaabababdaxabxbdbdxcdbbdbcacabdabbadbdxxxxaaaxcadbbaccdbabadabdxxaxxbaacxxdxaxabaxbxbxxaabddxacbxxdabdbacbcdbabdadbabacdxaaaxbaaxaaxadxdbxadaxcaxdaxxaxdababxxbdaxdaaaxbxbxcdaaaxcbbxcdddaabddbcbaaaacacaadddbdaxaxcbbdxabxxadxdbaacxxdxxbdadxxbabxcxdbaxxbaxbdaacdacaacbdaabddbabbdbaaadaadabaaabdbacdbdacadbabdbcadbadacdadbbcdaabcxadaxcadxxdxxaaxbdaxaxaacbbbacabbbaabacdbcbdbbbacdxxxxxcbaadadaxdadabdbbaadbadacdbdbabaaccddabaaacadbddbabdaxxdxaxbxxddbaxxbdbaaacaacddaacbaaacxdxbabbbdbddbxdaadbxdadabaaacdacddbbdabbaxdxdxaxxaxxaxabaaxbdaadaaabdbcaddacdddadbabbaxbacxxdaadaxxabxaxbdxxbxdxxxdaabxaxxbdxbxadaxabbxxaaabaxbxbdxxdbdxxaaxcxaxxdbxdbaadxaacdbddxxxxxxbdaxxdbxddxaxbdxccdxcxxxabdxxaadaababdbdaaabaaadbadbaxxaxdaddxbabaxbxdbbxxbxcdaxxaxddbbbdbcbbaabdabacaadxaaaxadxaaaxaaxaaxbxxxxdbabbxdbdxabxaaccadadacdabcbcbaxxbxbxacadbxaabacdxxbxabdacxxxxcxabxcdbdxxbxdxaaxadbaxbbxcadbxxdxacxxdxxbabaxadaxdadxbdxbxaaxxxxdxaaacadbdabddadadbabaaaxxcxxaxaxxxxbabaaaxxxxbdbaadxxdbaxabbxcabxaxaxdxabxbacdbdbbdadadaaadbdbdbaadbdaadddaaadadadacdacbbacddacxdaxaddxdacxaaaxdaxcxxxcccxaxaaxxxxbdbbxaxxbxxxxaaaabadaacbxaxaxbbdxdabdxxadbbacdaxdbaccxaxbaaacxaaxaabaxaxacacxxaacccadaxxxabddbaxdbabxdadaaaxxcxbbdxbaaaxadacaaxbxbbcxaaxxxxbaadabcacdbbaabdbcdbdadadacacdbacxxacdaxbxdaxbcxbxxaxxxacaxdbxdxxxxaacbxadxbadaadbaadxxcxbbxcdadbbacbbbdbcaacbbdbdbdbdbadaxbxaaaadbdbcdbadabcdbbacdadababxbxdxxabxcdxxadaaabbbadbadbaabaaddbadaaacbcdaaabaabdaaabdbadaaaxdxaxxaabbdaxxxxxaxadxaaxxcbxdxxbbbxbxxxxabdxbxcaabxcbxaxaxadxadxaxxdaaxaabaxxaaacxbdbdbbcbdadbabccbdbabdbdbbaadaaxdadxbbbaaacadbaaadaxdaaaaxaaxadadbaaxdaabbdaxbcbdbxxaaacxxdxaxxxaaaadbbbddbccbbbdacbdaadaddaaaadbadbbacabaabdadacadbdbbbbbbacbbbadadaadabbdxxxxaxxacaxbxaxaacxabaaxaaxxcbdbdacaaccaababadbaxddbxbbacdbaxabxbxaaxxaxaxaaadxxxaxcxxdaxdacxaaxxxxaaxbxbbdaxxxxacxaxdadadbaabxabxxxxdbbaxxccbxdxxaaaaaxdaaabacbdbaacbcdaccabdbdbddbbdaabdbaaccbacdaaaabaaaabcbdaacbadaadaccxxxbbxxbxaxxxadbxxxxbadbcxxbbdbxdababxxacxxbdbxdxdxbdxacbxxdbxxaccbaxaaaxxdbaaxxadbxccbxbdaxabaaxbxbbccdbbdadaacbdbadbdbxcxadacxbxdxxaccdbxddbbxxbdadxxxcdxxaaaddbdbaacbbadabcdbaabccbdbxdacdaxcxxbxbxxbcxadacdbacbdbaacaacaaaccdacabacbbaxbdadxacdabdacaadadaacdadaddbddadabaaacadbbaadbdabcdadaaaaaxdxaxxcbbaxbxbaaabxaxxadxacxaxxcabaxbxxxcxxxxdaxddbbcdaxdaacbbxxaxaaxbacxxdbbdacdbdbdbacdbaddbbcbdbdabaadbadbcdabaabdaaacdbbdacbcaacbxcaxxbaaacbbdbdxxxcdbabcdbdacbaacbabdaacbaxxbxdaxdaxdxxxcxaxccaccaacaaddaacccbacbaababbabbdadadbbabbddbabbdaacbcbbaxbxdaxxcbdxdbcdbbdaaabacdbbaaabdbdxcbbxccaaxxaxaaxxaxcdaxxxxbdbaaxdbadbbbxbaxdbdxxxxxbdbbabddbxxdbdbxcxaxaacxaxcdaaxabxxxxxaaxdaccxxbaxaxxxbcbxacbxxxxxaaxdaaxbxbxdxxcbdabacdadbacbdabddbacacddaabdbacbdbaaaabbbababbbacbaaacadadaabdbdbaddaabaaadaadxddxxxdxbdaxaaaacaaccbaacaaadaaadadaadbbccbaaacdaaabxdacaxxaxdaxaxcxaccxxbaadxbaxxaxxxxdaaaacdbabcabacbdbbdbbadabdacbdbdaabaaabcacacaaxbaxxadacbxbbbaxaxxbbxaaddbxaaaxabdxxdaacxxcxcdxadbacxxdxaxxxaabxbxdbdbbacdaaaaabcbbdbaaaadabbacbxbaxxbbxxadxcdadxxdaxxxaaxbbbxdbxxxcadbxaxaxdbaaabadbdaacbaabaaaaaaxxdaxaaxdxxcxbaxbxaxbabxxcxxabcxbababaacdabdddaaddbcdaacbxadbxcxxacbbxaxcaabbbdbaxaxxaaxbbbdaadaaaabaacbdacacbabdacaadbbadacaaaaccaadbdaabaccadabdaaaaadbdadbaaxddxxxxbbdbxdaaddaaxcxxbbdbbaaaadadbadbbaaabdxaxaaaxdadbdbddxdbxdxdabdxaaxbaxxxbxbaaxdxdxdxxbaxxxbxaaxxdbcdaxbdbbcbdbdbddadbaaacacacabdabaadaadxbaxxdbaacbaaccaaaaaccbbacadbcbabbbaccbaxxdxaxcbxaxcacbxxbxbadbdbcccbcacdaabdbdaaacbaadababcbdacddadaaabdbaxaabaaadaadaabdbdadbacbacbdbbbacacabbaadacdbdxadxaxbxacxaaaaaaabaxdbdddbaadbdbaccbadabaadbdaaaaaaaaaacdbadaaaabaaaadbaacadaccxacxdbxdbxabbaxxcxxdabbaxxxaxxaxaadbadbaxcbacbaadacdbbbacaabdbdbabbaadddacxdaxxxdbaxxxdxdbaacbxxdaxxxxbbaxdbbabbxdxacxdxabbdbabxxdbaxdbxxxbbxxxcxbaxxdadbbcxxxxabdacaacacbbdbbdbbdaccdbabbaabcbccdbxxcxxbxxbxaaaaabababdaabadaadacdabdaaadaacxbaadaxxxaaxxbxxxaxbaabbxaxaxaxaaxxxbaaaddaxxdxxaadbxcabbxxdxadxabdbbdacacaabbdbbdaaacbcbdaaaaababdbadaaabxadaadaabdaadbadddaaccdadbaddaadbacdbdbaadbbbdbdacabaabbxaxaaxdxxxxxaaxxxcbdxaacxbxxacbxcdxdxdxaacbxdxbbxacbbdbdbdbdbdbaacbabxaabcaadaaacbcaaaaabaxaadxadaxdbbdxcdbadbaccbaacbcdaaccaaadabbabadaadabaaxbbaxdbdbdxcbdxdbdbaaabbadbcddaaadaacabbcdacdbxxxbabccbccdaaxadbadabaabdbaaaaadaacabaaaaadbaaxxaacxadddabaaaabaacdbbddbbdaadaaaxaadxacdxxxcxbdbbadacdacacadbacbabdbdadbcdbcaaaabacdabaacbabcdbbacaxxxadadadadacbadadbabdaaaddbadaaxxxaxxbaxxxbxxxdbacdbdaxaxdbaxaabadacdaabbacbacaabdaaacabddaaadbaadbcbdbdabdaabdabbdbdaaccbabdbbabacdddadbdadbxdxbcxxxbdxaaccxxxxxadxacbdabaaaccbaabaadacdadbbdbadxdaaaaaxxbaabadbacdbcdbdbacbabdbxxbaxbxadacxxxdbadadbacdacbcdbdacaabacabcbacadbdabddacaabacaddaaabbbcaaxdaaxxaxxaxxxcxaadbacdacbbaaaadaaaabcbccaxdbxxxxbxbdxxacxxaaaxaxaabcdbdbdacdacadabcaaddxxcxxxxxbbxaxdbbddadxxabdxxacbaaaxaxbdbaddaaacdacbbaaaadbabdxdbcdbdxdaxdxcbxxaxxbxxcaxxxxbxbxbadxxbxaxxxbxbxbaaxxxxbcxcbbdaxdxxbxbbxbdbxcxbxbxxababxdbcabdacbdabbbaaaaaaxxcabxdaccxxbbxxaaxxcxxdxaaaadacdbaadbdbbdadabdaadbabdxbaxxxaxcbdaxxdxxdbbbbbxdxdbcdacbadbabdaadacbcdddxxxxbdaccaabadabdbbadaacadxddacaxxaaxadxxddxaxxbaxaadxddbxacxacxxxxcxxxdxxdbddbabaaaababcbbaaabxadbaxaaxdxbaxxbxabdaxaaxxaabaabxaxadxxacaaxabcxxxxdacxxaxbxacbdbbaaabaacddacbdaadbcdadbdbdbbdbacadabbbdaadaxxxxxabaabaxxdacaaaacbaaadbdbdaaacbaabxbxbbbxxxxdxxxxdbbxcaxxxdaxdbaacxxaaaxacdbdaadaaaabbdaaaacacbbabddaadbbdbadaabdaccdbbbaaacdabdbdbcdbbaabbbdbbdacaabdbxxaaaxaddaxxxxxbxbxcaxaaaaaxxaccbbbdddbaababcdadadabadadbabxacxxdbabaxacaxxbcabcabadadbaadbacdbaddabbacdaaabbdaabbaabdbbaadbbdaaababaaabcbbabxxdxaxddxdxdxbdbdxxdbbaxaaaxdbxaaxaacxaaxcxaxbdxaxbaaxaxadaaxxbxaaadaxxdxxadxbxaxbbcdabbddaadbcbdaacbbaabaxbxbdxacdbadxbbdxxxxdbaxcxaxaxxxddxcbadacxcaxxbaaaaadbabbacbaaadbaadacdadabdabcbcbbdabadbaaabacbbdadacaaaadbaacbdbaaaadaaadaaaadadbacbdbdbaaxxbdxaxcaaadbaaacacaaxaxxadbxcaxaddbaxbabddbbdxadacdacdaabadaaabddabdababadxxxxxxbabaaabxaxcdxbcbaabaacbdbdbdaadaaaababbcdbaxaadadaaacdaabadbaadbadxdxxbxddxbdxxacdadxbxxaxxxdbbabdxxdaxaaxxbaaxxbxbaaxcxbxbbdaacxxbdaabxbdxxxabxxxdbdbdbcbbaaaabbcdabdadbdxxdxxaadadxaxacxbxxbxdbxbacdxacdadaddbaaaaacdbdadabdbxaxxbbacacaxdxxdadbcdbbdbadbccacaxdadbdacbcacbdaaaaadbddaadbcbdadabbaadacbaaacbdababdaaaxdadaxxaxdaxxbadbxabaccbdaaaacadaddbdaaacdadbxbaaxdxaaaxdxdbxdaxxcbccbabaaaaaabdaadadbxxadabbdbacdbaaabbdbdacbbcbddxdxaxdxbxxxaxcdbddbdaxxxbaxxxxaaxdxabdbcaxxxbxaxxdaadbabadacddaadbbdbaaadbdbbxcbdbbxaaaxbbxdbxbdxxxxxdaaabaaabcadbaxacbbxbxabbxbxxaxdxxxxxbcaxbxaxcdbxxxxxaaabaxbabaxdaaaaaabdabaddbacadbaadbddacbbacbdbaacbbbxdxdbbxxaxdxxdaxcxbxdxacxaxacaadaaadxcxbxxxdbaxaaxbxabxbaxbdxaaaxbxbccadaabbadacbaacadacadaxxaxaxxdxbaxxxbbddxcxxcdacaaacaaddaabbaadbaabxdacxaxxaxbxxacbxxaaxxdxxaaxbbdaacxxxaxbdxxdabxxcbdaxxxadaadadadbacdaaadacadbcdbbbbaadabxabdaabdbabdbddddbdbdbcaacdaccabbacaadadaaabaadadbaaaaccdbbaaadbdbabdaadbaaacxxxbxxxaaxcbabcacacbaaabadbdadbbacbdxddaxaxacdxdxxdaxxxaaxdbbdbaacabdbaddacbadaxxxxaaxxacxaaxxbbbcxxdabdbabcadbaacaaaaxaaxdxcxxdbcabxxxbabcaxdxaaaxabbdbacdbaaacdadbcdabbdacacaaabaabdbabaccaabcxbdbbddxdxbdxaxxcaaacdbbaaxdxbdaaaxxbbdaaaaaaaaaaadaaaddacaxacaaxaxbdaadacbdbaacdaaadabdacdadbdbaabbbcaaabaadbcbbaacacacadabdacacaaacdbababbabadabdbdabaabdbaaacxbbxabcxaxdbbacxadbaxaxbxaaaabddbccbaabbaabcdbdbaxaccxbdbddxxxcxaaaadbdadacbcaabdbbdaadacdbabcdbdbcdbdaddbaxxaxaxbadabaacdxxxxbdbabxaaxdbaxxaxbdbdaxaxxbdaaxdaaadaaddadbabaacacddbcbadbdadaacadaacaaadbaaaacdaadxbaxdxdxxcxaaxabxbdabaxbxxadxxadxxxaxbacabacbbacdababdaaaaacabdddbaaaaadacdbxxbxxaxaxdbcaacdaabcbbababaaccbacbabadaaccaacaxxxxdxdddxcaxxxxdbaaacdbaaaccxabxcbxxxabxxxadxcxaxadbdxabxaxxaxaxdbabaaaaxdadabccaccdbcdabbbdaaaaaaadbbxxbxbxadxxaaaxaxxadacddaaxaxaaadxxddxbbxxacxxxaaabbadaadbdaabaacccbaxabcacdxaxaacxbdbaxxdxxbaxacaxaxxaacxcadaxxxabxaxxbacbxdaaadbaaaddaaaxcaxaaddbdacdacdababdaabcbdabbacdbabaadaadaaabccbabdbdbddaxdxaadabcbbdaababbbaaacbaaaaacbcbadaxxaxaxxaacaxbadbxaxxbxbxcaxxbdacbdacbaaaaccdbaadbcaaxxxxbdaabdabbdacdbbaccbdbbbdaaaababaccdbacaacbdbcxcdbxbcxaxxcxbxxacadbaxbxxcbxxdxbdaadacddaacdadaacbxdbxbdxadxdbxaaaacbdaxcxadxabdbxxaacaxxdacabdbdadaccccddaccaaacaadabcaaaacbacdacdbdacdaaaacaddaxcaxdxbaxbdxxadbabaaadbbaaabdbabbdbbxdaddaxaacdbxdacdbaaaababbcdadbabdbadxabacdbxaabaabaadacaaabdbabadaacaaacdbaaaaaadaaaaaxxxadxcdaxaacaaxdaaaxxaxccxxxacbxbxxbxdaxaadbcbabddbdbacbaaabbbdbbbbxxxbdxxacbdxxbaxxaxbxacbbxdxcxbcxxaxxaaacdaxbxxaaxaxdbbxxxabxdabxaxbxcxcbaxbxcxcxbxbabxxadxxbbcdabaaaacbaadaadadbaacacadbddbxxdxcbdxcxcdxcacxbxxxcbadaxbbdbaccbcadabcdadbaadaabdbddbadababbabaxdbbaadaxxcxaxxadabbbcbbaaaaaccabbbabaaaaaabxxbdbxadbbdaaaabacdadbabacbabaaaabbxbbxbxaxdxdaxcxxabdxacdbbaabdacbdabdbbadbbcdbdababcbbdxaabdbaxdxbaaaaaxxxabbdaxdxcbacbxxbbaxxdxcacdacddbcxxxcxbxcaaxbxxxbxbdxbaxxxcbxxdxdaxaaxxxddbdbdbxxdbaaxaxdbaxcaaacxxbaxaaabaacbabdbdabdbdbbdbdabdbdaabdaacaaaabdbcdxbaxxdbxbacacbbaabccdbaadabbdbabxxxcxxbxaaxaxxxdaxabxaxxaaxdbcbxcaxxxacdacdaaxxaxxdbcdaaaacaaabaaaaxxaxbdxabdbaxaxadaxxxcxxdddbxxacxaxxacddaxxaadxbxbxdxxxbxxcxaacxxddxdxxcdxdxaxbxbxxxxcxaaxbaadaaxdxdbdbxxxxcxdaxxxxdbaxbbdaaaxaaacbdadaacddbbbdaaxbxbaxxaxaaabbabbdadaaabbbacdbabbdacbbadaaadaadadacbacbaxxdaaaxbxdacbddbxxacbdabbdadaaddaccabaaaaadbbaabbaabbaaaaabacbacbdacacaaccbbababdbdbdbdacbbbadaabdacaabbdabaaacxxdbaadbdbdbccacbacdbcdacdaadaaadbacdbbbaabdadaaabbaacbdabdaxaxaxbaxxxxxbdaadaxdxaxxdaacaxxadxaaadxaxbaxxdxbxcdxccxxxxcbcxxxdaaaxxbadaaccdbbdaaadaacbadxaxabaxdxcxadbcxabaacaaaaddadabdadbcbaadaccdabbxxbaxcxaxcaxcxxcxaxxdaccbdbaxxxxaaxcdbxxxdaxxbbxbbbcdaxbxxacaxaxxdaaxbbdaadabdaaabdbaacaabxabdxxaaxxxxxdbxadbddbxbdbxdaadbdbbdbadaabadaaxacdabxabcaaaxbxxaxdxxdxxbxdxxxbxadadbdbxxcdacxxxdabdxxcaaabxxaxxxaaxbxcxxdbaxxxcacxxxxdxccxddaddaaacaaaaaddbacbadxaadxxbbdadacddadbacadbacbxaxxaxabxbaxaxbxaacxbdaxcdddbxxadxxcbdaabdbbaaaaaaacdaaadaxdadaaaaadddxacbadbdacadabddbaaaxdxcxaaaxxbadxbbaxxdxbxbdbacbdxbxaxbaxacxaaxdaxxaababbdabcdbabaacdbbcxacdaxbaxdbxxbadbaadbadacabacbadabddxbcxxbaxbbabbcbcbbbabdacdbbaxxaddadaacxdxaabdabcdxaxdxacxxdaaaacdacabdbdbaacdadadbdbcbbbdabdbabdacdbbbdacabdadbdbadacdbaccdaaddabbacbdbdadadxaxbxccacdxxxxaxbaxxbaxcaabcdxdxdxadxdbxxdbdxadacdxcxxxcxdbadbaabdaaabaabdbdxabxxxxxabddbacdacbbbdbaaacbaxxacdbabxxcbxxaxbxcaxxdaxacxabxbxadacbxbbaxxcxbdbaaddabaaaacaadabaxaxadaacdabbdacbdbddaddxdbbcbdaadacdbaaacdaaaadbacaabxaaaxxdxxxdbdbdxxcxxbdbdaaacaadbdabcbaaadbababbbdbdbdbaxaxxxbadbbdxxacxdxaxaaxbabcxxxbxaddaacadacdadacbdbbbdadaadxbdbxdbdbxxccxxacaxaxacadaaaaacbdadaabacdadbabxadaaxaacbaaxdxxaaxxbacaaxadbdacdaaacadbadbcadadadbbaadbaacdbbabbacbdbbbdbcdadbacdacaxdxxcdaxaxbxbaaxdxxbxbdxdxdxbxbdxxaacaaaxacdxxdxaaaaaxaxxbbcbbddbdbcdabcaaaaxdaxxadxdaacbxxcdxcdaadadbabaaacacbaddacdaaadaccxxdxcxaxdadabxccxxbbdabaabacaddaacbacddbbcdbbxxbdxaxcbbaacadabdaabdddacdaabxbdbaxaxxaadxcabxxxxxaababaxbxaxabddbbdabaacacbddadaabbaaadadbaadaacdadbabaaacdbaacbdacaaabdbbaadbadabdbccbaadxcxaxxbdxxaxxbbbcdaaaabdacaadbbbadbdadbadbaaxxdaxdxxaxacxadbxbaaxcdxxbaxxbacddaadbcxaxxdxxaxxaxaxaaacdacxccbxdxxbadadbxdxxxxbddadaaacbababbaadbbbacaaaaadaabaaadabacbdbacaacdaadaaaabaaabdacdadacaaaacbdxxxaxbdxxbdabdxcdbxdacxacbdbaaddbabacaadbxbbdxbaacbcaaacdaaddbbacbddbacbadaaabadxxxbbbadabdbxxxaxxadbxaxxabaxbxaxbaxxxcxaaaxdxaaxxxxaxcdbacbacdbacacbbacadbbdaddacaacbbaacbdbaaadxabccdbdaacdbbdaacbdaddbcdbbaxadadxxdbcxxdbccbbaadaacadaacbxxxabbddbdbdaxxxbxbdxxbxxaadxxbxxaabbbbdxacdabaxaxaxaxabxaxxbbbdxxxxdaxxbaxxcaxxcxxaaacabadabdbdabbaaaacacaadabdaaacdxxdaxxxaabaxaabcaxaxaadaxaaxxaxxxdabadacdadbbdbadadacaacadacdaccbddbcacdbdbacbdadaxxcbbaxbaxxdbbaxbdxxcbdxxbbaabbdbbdacabaabaaxdbbxaxaaxxxcxbbxaxxdbcaacabdacdbacdbdaabadacabdbdacacadaaaacbbdaadddddacabbdaadbbdaabcbaacbbcabbcadaacaaaabdacdbdadabbacbbabcdaabcbxxxbdacdbacddabbbaaabdabaxbxxadacaaxxdaxxaxxxdaaaacabaccdbbdadabdadbdaddaacabaacbdbaabbbdbdbxbaxdaxxaxababcadbabbacdbdadbdaaabaaacxxxbdxxaaxxaaddbxbabbabdabacdacdbcdadxdbdaxbdxxacaxdbaxaabbxaaxxcaababcdbbddadbddaaadbadbdacbbbdaaadaccdbbbcbbcdbadbdabbaabdbabdadacbbdaxxxcdbxxcccbabadbbbacabbcaaacdbdbdabbaadbaadaaadbdbdabdbaaaabdbacxcbxxcaaxdxxxdbxacxaxaxaaxadabddxbabcxbabaddadabdbaaacdaadbaabdbbbcaabdbaxbabxxxxxaxdxxxbxaabaxaaadxaxaaxdbcxbbxbxaaddxbacbdacxaabadaaxadaadaddabdacdaaabadadbacbdaaddaacaacacbcadaabbdbdxdadxbxcxdxxaxdxxxaabaaxcbaacabdaabdbdabdbbdaaaaacaaabxxxxxdxcbbxxxdxdaabbaacdadbdbcabdbaacdaaaabdaadbacbddacadbabdaaadabdaccdaadaaaaccdaabaacxbxaabxbxdaaccbxbbabcbbadaaaabababbbcbdabadadxxdxaxxacdacaaadbacddbacdbbaadbdxaabdbbadbdbbdbdadxbcxccbaaabaaaaadxaxdbbabxacacacabbdaddaaacdaaaddaacaabdaaacdbacdbabaadbadabaaabcxaadxbxcxxacdbcdxxaaxaxaaaxcbaxxxxabdaxxacxdbxaxcxaxcadaxaaaxdbxdxxdxcdaaxbaaxbadxbaabdbbaabdadbaabdbacadacbcccabcxbaxxxaaxacbxaacxxabxxxaxdbbbddbbbaaddaaabaccadxxaxbdbacxdacaxxxbabaxadaddbdbbdxacxaaxxaacbbdaacbbaddbdaacdbabadbaacdxdxxdaaacaxxadbaaaxbccxcadbxcxaxdxxaacddadacadbacdbcababbxcbxdbaadxbxdaadaxdaxxdxxxxaxdxdxxacbdaacdacaabaadbaaadaaacadbdxxdbdbxaxcbcdaaaacabacbddbbadbdbaxxxbxcaaaaaaddaabdbdaadadabdbbacbaaxxxaadbdbbaxaaxxxdadaxaaaaxxddxxbaaabaacadbbdadaaccacaaxxxxxbbxxdxxadbdxcbbcacbdacacdbdbbaacbdbccdacbdbaadaacadxxacbxxcaxbcdxxxxxxxdaxabdaddbbbxdbcbdaddaxxxacxaadxxbxcabdabxaaaxbabxabxxxxxxccaadaaaaddbccdabdaaabdacabacbdbbaabdacdbdadbcadabcxdxxaxxbbaxdxxxxbxcdxdadbdbacaacdadaacdacbdbxxxxcxacaabacabadabbacdbbbdaaadaaacdabaaaabdbbxaaxxcxxxxaxaaxaxcdacdadbbcdbddbacbdaababbaacbadadabdacaadacbbcbadaaxxxaaxaxcbacaxbxaxxbdaaaabbaadadaaabdabcdacadxabcadxxaxdabxbxxcbacbabdbdadaaaaaadabacdabbdddacadxaaaaaaddbdbbccdabbdbaabadbdabbaddacxxdaxxbxacaabdxdxxcxacbxxbacxxbxxdxdbcdbacxaxxxaxbddbbacxxabdxxxxbadbxxbaaacacddbddadaadacbdbxaxddaxxxdaabxdxxdadxacbcxaxadxaxxdxabxxxxadbaaaxaaccxaabaxcddacdxxxaadaaacbacbbadaabcbcbabddabdbadacaxabaaaaxadxdxaxxaababaxxbabcacdaaacdabacdabaabdbbdxadxabdbxcxxcxxxxxaadbxdxbaxcxxbaxxxbdbaaxaxabacbbdbbadaaaaacddbaabddbxbxaxxxdxaadadxxcbcxdxaxdbddaaaxaaxbxxxxaxaxcdbbdbbacxadbxaddxaxxdxbxcbxaaaaxadbcaxxaaxbddaaxdbaxacbdxxcbabdabdacbdbadbcdbaaaacbaaacbdadaaaaadabadbdbacbaabbbccacadacdxdadbxbacbacxdbxbddaxdaxxdabxbxaxbdxbxaxadbxxaxxbxbabaxabbacdaaaaabadbdbcxxbcdadxaaddbaxxadxbbxaxaxdaxdaxxcaxxaaxxbxxbcbxxxabxxxbcdxxacxcxaaxdbdaxdaccbxbxbxacaaadbdaacbdabbdaacxbxacdbdbdaadaacbaaaaabadbbadabadbbddbdbdacbdbbcdbadxxbxxdddbaxabdxcdaxbxdddbxxaccdxbdxcxxxadxxbacababbbbacccbbdbacdbdaaacaadaacdaaaxxxxxbbadxdabbxdxcbacdbacbadaacbdbbbbacbdaadbbcdbacadbdbaadbdaacddaaaacacabbdbbaxaaadxaxcxxddaacdxbxxccaxadaabaaaabacaaadbbaabbdbccxdbaaaxdaxaxxxxxabcadbadaaaccabbcbaaacaaadabaxxbdaaacxbcbxabxxabxxdxdxbxxxxbdaxccxxbxdxbdbababcdbdbadbaaacbxcbxaxxdbaxxacxcxddaaadadaacbcdbacbadaaadbaxxbxdaxcaadbdbaabbcacbxbaxxxxxaxdabcbbaaxadbcbxbbdbacbdaaaabadbaddbdaabdbbcacadadacbbdbdacadbaadacbabaccdaddbaaadaaaccdaaddaabaabbdbadbddbabbdbdbxacdadbxdbcxxcaxxdxcbxxbbxxbcxbxbdxxcbaadbdaxxcdaaxdxbaxxabaaaaaccbcaaadbccadaabaaaadxxxxaadbbdbxaabxbaaxabaabcdbdbcaacbabaacbacbaaaadacbbaadaaxbaxxbxdbxadaxxaccdaaaabcbdbaaacaaaddaabbdadadbdadadaaababadacbdaaabcdaacabacbdbdxcxxbbaaxacxdaaaaaaaddabbaaadbabaxbdadbbaaaacbdabbdbbdbaxbadxcaabdaaababccdbdaadaaacabbbdbdbdadacbcdaacbdbddbcbaabaabdacdadaacbcbaadbccbdbxxxcxaxxaaxcdadbdbbxcxxcxaxccacbbxxdxaaxbcdaaxaacxaxabbxxxdxbacdbaaadbaaaabcdbaacdaacaxbxxxxxbacbdbabbacacdadbbaadaadaaadabaadaadabdbbabxxxaxcdaabxxxcxbbdaacacacbabadbaabdbdbxdxxbbbdaabcaaxxdxdxbxbdxbxxcaxxxdaaacxxdadaxxxbxdbdaaxxcbbxxaxxbaaxaxbbdxcdaxbxdaxbbdaaababbacaaacdxabbbaxxxdaxabdaaxdbxdxaaaabcbacbcdabdbdbbbdbadbacacbxadbxcdxxaaddaaxxaaxxcxdaxbaxbaaaxddaabdbadbcabdbadaaadabaaabdbacadbaaaxaxcxabxxabaxxxxbababaadbbabadaacaabdbdbabbbacdaaxbaxdxdaadxdbbxacdbcdxxbdddbaacdadbbbabacdaccaabaacaadadadabaadbabaxxbxxbdxxaxaaxbxddabbabxdxbdxcxxxxbdabxaxdxbaadbddbbxxdxxbdxxxxacxbbcbdxadxdxabcxxxxaxxaxaxaacdbaabxdaxxxxacbaxdxxcaadbdadaadbdaaaacaabdabdbaaadbbbababxxaxdbadabbxxaaaxaxdaaabbbddacbdabcdabdaaacddbbdaxdaxaaxxaxcxxbcbbaaadbdbdbdadaabbdxxbdxdaxxaadacxxdxcaaxacdbabcbbcbbaaaacabaaaaxdaxdbxdxxaxbaaaxaaxxbdxbaxxxabxxxaxxacdabxdbbxxxaadxdxxxbxdbadxacbaxaaaxaaxxxxacxaxbdaxacadbbcbddaacbdbcbaacbaacaabaabadbdabdbdbddaadadbacacbbbbbcbdbdbdacadaaacbdaaacxxdabcxdabaabaabcaabdaabadbdbdacddacbbaadabdbacadbbaacxcdbxaxaxxaabcxxxbxaxxbxabxxdbbxdaxddbdbxcabxxbbxacxbcdaaaacbdbdbabdabaxcxbdacaxxaaxxaaaxadxaaxaxxccxadxadbaxxxxxdadaxdbxbdbxcxbxaaxaxbadbxxacxxxxadbaaaaadaaaddadacbbacaacdbacaaadaddabdbcacbccbacbacbabcbxaaxdbaxaacdbdbbdbcacbdbdbaaxdbacaxbdxaxabaxxaxxaaacbxbxxabadbdaxdbaaaaaadaabcabadadaddaabcaacbabadadxdbxxxabxabxxadxxaxaabxbbdaxabxaxcaacxbxaaaacxacaacbabaaaccdaaabdxxxdxbdaaadabbaccddaaacacbbddabaaadxbxaadxxxdadbxbcdxcacxxaxcbbacdxcxxadxaaxxxdbxaxbabxaxdxaxxacbdxbxdxaxaxbxxxbccbdbaccaaacbbddbdabababcddbaxxaxxbaxaxdbxaaxxaxaxxbxxdbxcbaxxxxaxxadxabxbxacxdadxaxxabdbxaxxxxbxxcbdbbxxxccacbaxxaacxcxdxcdxaadxxdaaxcbdbxxbdbxbxaabbdxdxbaxxxadxaxdxxxxxdbbbabbaxxaxxdxbdbdaccdacdaddaadbbccdacdbacadaabdaadxadbdaxxxxxbxxbxaxxadxcdxbcdxaxxbadbadaaadbaadbadbaccccdacdbbacbdbdaabadaabdacdbaacbadaadbdbacdacxdadxaaxxdaxxaaccxxxxabdadacbadaabbdbabaabdaxaxbdaxaxaaacaaaabaacaaccacdadabadbaaabxdaabdabdbacbdacbdaaaaababdbaaabadabcbbdaacccdbbacbdaacdbacdabadbdbdbdcdbbdaxcxaxxcxcxbxaadxdbadxaxxxacadbxbcxbxaaaxxdxxadxcxadaacbaababbdbacbaxbdxdabxxxbxbdaaabxcdbxxaaaxbacbdbdadbdbdacbbaaaaaaabdbddadxxbccdaaaaadacbdbdbacacxxdabbdbbaacabdaabdacccdxxaaaxdacxxdxxxabaabbdxacxaacxdbxcbxbaxxxdbaxxdabxabadddxxaxaxbxadbcxxxdxaxbdbdaaabdxxbxdacbddadbdadbaacaadabdbaabdabdxxxcbdaadxxadacbdxaaaxxdxdbbaxaxcxbdaxcccaabaaadaaaaaabaaacadbxabxxxaaacbaaaxadxdxaaacbbxxaxaaxcdbxacxbxdxadbddabdabdaaaadbbbdaxaaddxddxacdbadxxxxxxbacbbdxbaaaadadaadaabbbaaabdbdbacbxxbxxaxxxdabdbacadadaaacdabdaaacadbbabxbxdadbaxxdacbaxaaaxxxbxcdxaaadabaxxbadaadaaaaadaaaadabaabaacbdaaaxxxaaxadbaxxxaacbadaxacaadbaaadabdbbcbaacbadxxxdbxaadaacddadbabbaadacaadabbbabdxcdxdxaxxadbaaxxbxxdbxxxxxxxbbbbdacbbaacbdbaddbbbbaccddbdbdbbdbabaaacdbabadbaaaxaxdaxxcxdabbbxxxxaxxdxcdbaxxbxbcxdxbxcxbcaxbxbbxbaxxdaxcxaxaxabxabaaaaadbxxaaxdaxdaxacadxabddabadbddbcdbdabbaaadaxxdaxxadbbbbbabcbdbdacbdbdaabaxcaacadbdabaadadbaaabadbaabcdabdxaxaxbdadxxaxxbccxxxcxbcaaaxxaxxxxcbaadbacbbbdabbadbcaacdaxxdxdaaxbxdbxxdabbcxdadxcdxxbadxaxxxddxxbdbbdaxaxdaxaaaadbxxcddbcadbcacababbaaaxaxbdbaxabbcbxxxxbaxxxcxxcxdxdabcdbaaacaxaxdxbbaddbbbabbabbbaadxbcxbbxaxbxaxbacxcxddxxaxbabdabacaccadaccbdadaacbxxxbxbdaababbabdbaacddaxxdxbdbdbbaadacbaaadbdddabaaaxaxbxxaabxxxxaccbadddxadxdbdaxbxxxxxxxacxaaxaxcdxbxxbxadbaxdbadxabxxxaxbcxdxcxdbddbbcdbdacdababdxcxxbaxaxdxxaxaxaxcabaxaxabaaxbxxaacacbbadaaadbbcdacbaababaacaabadacaaaacxxcxxxabxcdxacdxxxxbaxddxxxabaaaabaadaaacdaddbaababdaaaaaacdxdxxbxdacxcacbaaaadabaaaxxxbbxbcbdbabadbadbdaacdacdabdbddbcadacxxdaaxbacdadacbdaabdadbdadabdbdbbdababcbdaaacdabadacdbacdxadaddaccdbaacaadaacddbxaxdbdxxxaxxxbaxbadbdbcdaadbbdbdbdabxaxcdacacadbbcbcddbabaaxbxxbaaaxdxacxadbcxcbbdadbbabaacccccadbbbcbaaxbdbxbdaaaaxcxxdxxdxxxcaxxaxxabcaxxdxaxxbxcbadacbaabcbadaccbbdbddaaabbacbdbcbddaacdaaabdbdaaabddbadaxbxaxaxbxadaaacdbbadbcacdacacccdbbbbdaddbbcbbaadabcbdbdbcxbxadacdbxdabdabaaacacacbdbddbacddbdbbxdbxbxcacxaxxxbaxaxdbacxbdaxbxbacdaabaabadbadbdbaaaaabadacdacbbcbadbaxaxdxxdxaaxbaxxaxxdxdaaxxdxbxaaaaaadxxxaxxbxdabdaaxxacdxxxacxaabdxxcaxacbdxaaddbdacbxxddxbaxdxdadaaxdbxabaaddbxdabdxxxaxxaaxdxdabxxbddbbbdaadaabcdababdaxaxxbxbadbcadbcxxxxdxaccaadbcaaabacbdaadbbddaccaacxdabbbbxxacxaaabdbdaabcbdaaaaaabdadbbcadadbdaabcbaadabaaxxaacadxxdaxcbxaaxaxxdaaacbxxxxaxabadxdxaaadbccdaabdaaxbxaxdaaaxbbxaxaaddbxxaaaxbaxxacxaadxbxadxabxaadacdbdacxxxaxcxacxabaababbaabdadacaabaaaaxaxbaacxaaxcdbaxdxbxaxdbacbabdbdbabaacdbbcaacdadadacbxddbaxxbbdxcdxxxcbaabdbadbadbdbdbdbbbdaaaaaaaaadabaaaaaadaaxxcaaxxabdxbacdxabbxacxdaaaaxxbaacxxbcbdxdbxbdbcxxxxcxaadadbaadaaacbdddaaccdabaaababbbaddaadaaxbdbdbdbdaabaaaaaaddaaaaadbacbaccbbaababbdaaadaadababbdbbbdbcddbdabdbacdbbabacdbacaadaxbaaaaxadabdadbaababdbadbcbdbdaadaaabdbbbadabaadbaaaaxaaacaxabdxxxxxxaaaadbaaadaacbddbcaacdacbdadbababbaacbdaadaaaacbdbbabadbcdbadadacdaabdacddabdbaaacabbxxaaaadbbbdbdadaddabacdabbdxaxdxxaxaabxadaaddbbaddxxcbcxbxdxadabbxcaxxdxabbaxbdaxbbxxaxaxbacdbadadacccdbdaacdbacdaabaaaaaabdbaabdaaxxxdbbxxcbddaaabdaaccccadbaacdbdbdacbdbbdaaxabadxxaaxxbxxaddaacxxxbdbdacaacbdaabaaadaxxxabdabdabcdacabadaaabadaxdacbxaxacdbxaxxxbxacdbacabbabbabdaaaadaabaaacxdxdbxxbxaddbaaabdacacaadabdaabbabadacbabdaacaacdaaacxxdxcdaxadxxaxbxdaxdabxaxxbxbxxacxxxbbxaxdxadxbcdbdbabxddadxdxbaacxxaaabaxxaadbxxaaacaacdbddacacdbdbdbdxcadabaacabcaabxadaaaddaaccdaacbdadadbaadadbdbadbdbadacdadaacdbdbcadbcbaacbabccadaddbaacdbbbadbdaxxbxaxbbxxaaxacdxxxdxaxaxxxxcxbxcxaxxaxxbxacbxabxacdabaddacdbbabaaadadaaacdbacdabacdbcbdxxdabxxxxxaaxbxaxcbadaxaxacxxcxaaxaxacxbbbaxxdadadbdaaaacddaaabbdbaacadbbbddbbdbaacabbdbaaxxaacxxcxxxxbxdbcxxxaaxxdxbdbdacdadaddaabdbdxxxxbaaadaxxdxadaxxxcdxxbdxaxaaadbaxdaaaaaddbdaaddbaacddbabadbbadbcdbadbacbaabbaabaacadbaadaaacadaacbaacabdbaaddacddbbbabbaxaaacbbdbaaaaabddaabacdadbbbcbcdadbxaaxabxcxadaaxbdxbxxacxbdbxxbxbxxxxaxxxcbcbbabxaxxcaaxdaxbbdbbbdbdbaabaaadbxaxaxaaaxaabaxxxdacxacaxaxaaxbxxxabdbcxxccdxaddxaacacdaaabaaccabcbaacadbdbaacdbadaaacdadbbdbaaaaddaaacadbdbddbabdxcdaxxadbbdbxaxaxbxaadxxbxaaxxdxxxaxaacxadxxbbddbbadbdbddadbdbbacbaaxdxbcxxbxdaaxbdbdbxxxdaxdbaxxdadbacaaaccdbababbbaaababcbbabaabadaabacaddbbdbadacbbbdbdbabcadbbbxcxbxxaadxcbaxacddxbxxxbadxaxxaaxbxdbadxxadabaxbaxddxxcxaxxbbbxxaxxxacbaxbadxxxxbxxdabbxxxdxxxxbacdabadbdbbadbdbacdbabacabaxbcdabcxbcaxxxaxdxxxxababaxbdbaacxdbxaxaxaxxdxbdbaxcdbxddxbxcacbxacaddaaaadaacdadbaabbaxadxxcbxxccxaxxdxbxacaddaaacdadabbbabaacdadbaadacbcbaabdxxxxxxaaxbaxaacaabxaxcdaxcabdxdaxxacbbadxdxxaxxabdbccdbaaddbabadaababdacbacbaxaxxcxbddbxxaxbxaabdbxxcdbxbxabxabxacaddxaaxabdbdadaacdbbababdbdbdbcdaaaacdbxxdaaxddxbxaxxdxaaxxaxxbaxaacdbddaadbabaadadaaabaaaaxxabaxdaxxxaccxbacxaxdbxaaaddbabaaccaaaababaacbdxxdaxdaaxxccbxaaxbxaxxdxcaxacdbabbbabadaaacdbadabacbdaaacdbbdbdabacdbddbcdadbacaaacdbabbcbabdbcbabdadabdbcxaxbabxaxxbxbcdxabxxbaxadabbdadacbbacbaacdaaaaabdbdxdxadxxddaaadaaaaccaaxbabxxcxaxcxbxbxxxdaxdacaxxaxacbbxxbxxcaaaxcxaaabcaxaxdxcxxxdxaaacxxddaxxxxbacxxdaabaacadadbdbcadaddbcaacdbbcbdbacaaadbdbdbabacbdaaacbccdbddacddaaadbdaaaadbaxadbcbabxxxdacxxaccdxxxxxaaxaaaadxaxaxbxxaabdbaababxadaaxaxacxxaxacbxccxaxxxbdbaccbbdbbcaabbbcbbbbbxbxaxaxbaxxxxxcxadaaxacxaaaaccdbdaaadbaaaaaccxcxaxddxddxdbxadbdaacaaxxxxcdxxxaxdxaxbxbdbxxadacxaxbddxdbdbbdabbbadaacaacdbddacdbdaccddbbaxbbbddxdbddbbaaacbbdaacaacdabdabadbbdacdabacaadbbaccbdaaacbaadacbaaadaabadbaadbabdbbxxxcaxxxbdabaaacbabdacdbdddaabbxaxaxxdadbacbcaaabacbdbbdbdbaacbabdbdbadaadabaacabadbcxxaaadaccbaaaaaacxbxdacadxcbdaaadaxbxbdbaxxxxbaabcacxcxbxbaaaxdxacdxdaabdbbdaabacababaaabcxbxddxaadbdbdbbbdaxxbxacxdaaacxaaaxxdaabababaabadbbadbaaadaxxadaxbaxxacxaxcxxbdbdxxxaxaccbacaaadbbbabadaacdbdbdadbaabbbdabdabaaaadaadaaccabbdbcabcbdbaadbdbacbbdbdaxdxxcaxxaxxxdxxabdxdxaxaxxbaadxabxbaxxadaxxxdaxxaaxxdxcxdxxxxxbbaxxbxaxdxdxdxcddadbxaxxxaabbadaaaabdaxaxaxbxcxdbbacxdxxbaxaaxbxxaaxxcadabadbaacadbdacdbddaxxxabcxbaabacbdaacbabdacbaadbcbadabacdabaacbdbbaadaadbbbbdadbadabacdbcacaabcdddbaacdacbcbdbbaaabadbbcbbdbbbaadabdbaaaacabcdaaaabcdaabaadadabccdaxaxxxbdxxxaaxdaaxdaxxxbaxdaxdxabxdbbxadaaacxaacxxxxaxxadacaacaacdadaacadaaaabacadaxcxxacxcxxxxxbdbdaxbdbxaaxbbdxdbaaadabcaaacbdbbcacaddbdbabdaabaaaabdabaaaaaabdaabbaabddabbcxaxdaaadbbbdacdbxaxacxaacxbdddxbabaaxbcbbdaaacbbcaaadbbdbabbabaabxbxxxxdxaabaacddbaadbbaaabbaabacbacdadadacacdadadbcadaacabaaacaababbddababbbddadaacdaaaabdabxdxdxxaadaacdabaabacdadaaaacdbadacdbddbcxabcdbbxaxbxxaadaaaaddaacdadacdaaaabbbcacabaaaadxcxdaabaaabdaaaadaadababaacxbxaaxcbaxxaaaabxxcxxxaxaxxxbcdxaxcbbaadabbdbacdbbdbbbaxaabxxxbxxbxbaabxccbbbdabaaaaadacdabcabacacadaadabacdadaacbaacbdadddbdaabdbbdabbdaaaadbaaaxxddxxadbabadxcxcdaxacdabaaaaaadbbdaaabdaaaabadbacbbcdbdbdabxxabxxxbxbdxadbabaadbcaabdabadbbddbdaacabxxxaxabdbdbdbabbacadadacbbdbbababdbadbdaaaacdababdaccacbbdbaxdbxdbxaaxaxaxbabxbdxxdbxcbxcaxaxdxxxxbaxaxccabcbdbdaaabdaacabaxaacaabxxcbdxxdxbcxxbcxxcababbbxxaacdbdaabdacdbbababbbacdbaacxxbcacbacaaadbdabaadadbdaccaxabaxbdabxaxadxaxabdabdabdaabdacaaadaabbbaaaacdaaacaaaaabxcaaacdaadacbdaabdaxcabbaaxxaxaxxdbaacdaacbcaccaabdbdbbacaaxdacaacbaaaadacadbccaaaccdbdacbbddbabdxxxdxxaxbabbacbbbaaaaaacddbaaabbadaadaabadbcxcxaxxcbadacdddbbaadbbbdabcadxxbdadabcdaabddacbcbcddaabdadacabbxdbacdxaxxxbxxaxdxadbcbdbabdbacdbdaadaacbxbxdxcxxbdbxxabaddxxabbxadxxxxdaaadaabbadbaacxdbxaabdxaaaadbccdbxbaxcbxxxbaabbabaabdbaabacdbcdbaaaabbcadabdadbcddaadadbdaadabaccxdxxaxcacaxxxaxbxxxddacbacbaacccdaddbdbbaadbaabaaaacaacacbxadaxxcxxxabacxxdxxxcdbcbcabaabaaddabbaccabdbdadbbacbdxaaxxxxbdbxdbbadabadabbdbaaaaadaaacbdbabcacababdbaadacaaaabaaacabdbaaadaccaabbbcdadaabdxxxcdaaxxcxadbxbxcdxbdabdxbbbbaxxaadxxxxdxaadxdbbdbaccadaaddababdbacbbdbaacbdaabacddbaabdaaacbddabdbdbbaadaxcddacxaxdbaadbdbbdabbdadaaaaadbdbdaaddadaabdbabaacabcccadaadxdxaxcxxxcdbaaacdbxbxcxaaxcdbxaaacabaaabaacdacabdabbddaaaaaaaababdbdbaaacadacbdbdacxcdaxbabxaxaxbxabcadxaaxdadxbadcbdaccdbdacacdadaadcdxaxbdaaacaxxbxxbadxxbxcxxacdbxxaaxxcxxxbdaxxxaxxcdbxacdadaaacdbdxxacxbxaacxdxabdxxdbcbadbaacacbccdabbcdaadbaaccdbcdaaabcdacbacbdadaabdacbdbadbdacaaabbdacaabbacbabacbcdbabdabaxdxxbcdaaxxxxdbddbdaaxxdaxaaabaxbacdaaaadaaaadbdaaaxdxdxdaxbcabxbdxxxxaccdbadbaaacbadddbacbbdabaccaaddxacbbaabdbbbdbacadbdabbaabdacdacbcaabbbdbacdbcaaadbadbccddbaxaddbaxcxaxxcbddbababaaaxxbdbaxxxxbdxbcacbcbaadaabbaabaacdabaacacdbbddbaadbdaacdbaxxaaxaaaxxaaadbdaacxdxdbcxxdaxbaxxxdaxcbdxabaacxaxbcxxaaaaxbaxacxbbabxacxaxxabdaxaaxabddbbxxxdxxdaaaaxxdbxxxdbdaababadbabcbadabadacdacabxxcbabdabaaabbbdaaabadbbccdxcxxxcaaxxcdaaaaadacacdaaacaacbbadbababaxxxaxdbxxxbaxbabxbxaxxbxdbaabbadacbbcdbaababaadadbabaabxaacdabbbcdabaabbaccbxxxcxbdbbbcbdacabaaabccdxdxxaxcdbacaacacxxxdxaabaaxbcdbaxdxbxcxaxxaxxxaaxxdxcdaacdxxxaxaadxacbxxdabcdxxadxaacbaxabxxcaxcdxxcxxdacdaxaacdbaabadbdadbbacacababacbaaaaxddaxcaxbdxbbxcaadaadabaaacbdabacbcxxabxxxxaxxaxaxbaaxdbcxbxxaxcbdaxxxxcxacadxadxddaxxxxxacxacaxxabxxxbxaxbbcddbaaadaadacdbbabaacbaaxbdxdaxaaxbxxdxbdaxxbxaxcxxxdxxdbaccdxccxxcacaxxaxbbaxcabxbaccbaaacdbbdbaaacbdbadaxxxxxxcddbxaxcdbxxdaacacacbdadbadabaacaxxaxxcdbxxbdbdbaabdbdacacdadaadbabdacdaxbdacaddxacbcabcacdacdaaaaadadbabbdbddacdacdbcdxxccxcdacaxxbxaxacbaacxxcxddaxxxxxaacdbxaxxacdxxcxaxdxcdaxaaxaaadaaaabdbdbacdaaddbdabxbbxxxabxbcxaacaadadaadddaadaaacdddacbdbdbdaxaaxxbxbaadxbbdbaacdbdabdacdacaabxxaxxabdaaccdacadddaadbcabxacdbaaxaxaxdbdxbadbdbabbdaacbdbadaacbxdbcbadaxxdbdacdabbacdaaaabaaabbdaaadxxxxxxxaadadaccbdabaabadacdaaaddaaaadbbaaadxxbdaxxaabxdbxabxaxxacbabdaacadaabdaacbdaacaxbxadxdaaxxabaxxxxaxxxdadbxxccxbdbxxxxxxbaaacxaaxaaaxxxdxdadbcbcaadaaaacdaaacaabdxbdacbcacddbadbaadaadbabbddaacadadbdadbbdaxcxbxxbxdxdbdadacdaaxaxaxdxaacbabxxbbbdaxbaxxdxxbacbaxxxadxxaxbaabbacdbabdaddadaabbabddadaaxbxadaxbxacxdxxaxcxxcxacbxxxbxbdaxxdbxbaadbbdxaaxaxxaxbaxaxxaadxxxacdacbdbaabadbcbbcaddbbcacaaaaadbbacdxcbabadbacaaaaadbddxacdaabababaadadadbbacddaabaxacxaabxxdxabdxxaxxdacbxabbxxbbdbadxaxxbdbdxbxbdxabacbxbxaxabacxaxcbabdbdabbdaadbaaadbbaacbbdaaadabdacacdbbabxabaxcxxaadaacxcdxxacxxxbbxxdadaxaxxbxaaacbacaabcbadaadaabdadaaxaxaaxxdabdxabaxxadaxbxxbdbxdbxbxbdxdbxddacbcdaxccbdabbxaxxxbddaaaaababdabbaaaabddacbabdaacdaadaacbdaxxdbbxdbxxaaxxxcxcdadbxcaacxxaxaxabxxxbaabdbxbxdbacxxaxbaaxxcdxxcdbdaxdbadbbcddadbbababaacxxaabacdbddadbbadabdadbddaxcxaxxxbaxbxxbxaxdaxxdxcaaxxbdxdaadbabcxxbaaaabcbacadacdbaaacaababdbbcdbadbbcaadbaacdbabacacddaadaxxbdbadbbbacaabbadbaaxbbxbbaaxbbacxacdabaadabdadbdacdaaacaadbdacbadxdxdxxdxacdxacaadaaxcxbdbbdaxxaxadadxaxaxxdxcdbxaxdbaaxadxxxxxxbbxbabacbdbbbccdbdacbbdaaxaacxxxaxdxxxxdacxxaaxbaxaaaxxbxaaacccbxxbbabxxxdbxbbxbxabxacaxxbaaaxabcaddaacbbbaaadbddaabbaabdadaxacdbdxaacbddbadbdbadaaaadbbabababdadbcdaacdbdacxxxcabaaccxxxbaaxxabccxbbcadbadbaadxacbaaacadbabbadbdacdbddaaaaaacbbbbadaabadaababaabdadaabaaabaaaadbaacbacadbdaadbadaaaxxaxxxacxdaaxxbxdxaaaxbaadxbdxadbabbaaxxacdaacabdabcbbacdbbadacxbaxbaacbdbdaabadbbdbadabaadbdxdbdbxxabdxbxbbbbadaaaaaadaadaxxaxacbababdaaadadbbaaabdbaxxdadbaaaacaaaacdaaabadaadacbacbdaxcdaacdxxxxaxadaxxxxdabaaxxaxbxaacxxxxdbacbaaddbdadbbadaadabdabbdacaxxabbaacbcacdababdadaxbdaaxxaaaaabaacdbbcdabacababbdacaaaxxacbbdbbdaaaadbaacaaaaaacbacadbdabdbabdbdacddaddaaabbbacaacbddadbbadadbaaaaabddabcbdbbdbbddaxaccbxxxxbxdadaadaabdaaaabcbaaaadbaacbaaaabaaxaxaxxbaxaxaxabaxadxxaaxxcabxxbxabbbxbaabaaacbdbcadaabdaaaxxxxaaxadxaxbxdxxaacxdxdxxdbxxaaxxabdbabxdbdabaacxdbaxdaacadababacbabdaadbaaaadadxcxxbbdxbacaxbdaxaaacbdaacaaaabbaabacdaaaadbbbbcbadaaabcbaaadbabaaddaaxbxxxaxbaxaabacdxxaxbbbbxdaxcaxaxxcxdabxdaaxxaaabacxbcbdxxabxbbbxbxabcxxxxbabbdacbbbbdadababdababacdbdbcbaaacdacbabdadabadbbbdbdaacaacdaxadxxbxaadxdxaxbxxaccbxcxbxxaxxxdaxcbxadaxabaxcxbxxaxbxxcaaxaxdaaaccbdbbadaadaaaaaacbxdxxxadbaaaaadxaadbaxbdaxbaxbaxdxxadaabbadbxaabdbbabbaacbadbadaacaaaacdxaaxbbaaxxdbdaxxxxbxxxaxbxabacxxabbxaxxxxxxxdaxdxdbcxxacxaacbdbxxxcbbdbxxaabbdadbddaacbabaaaxbbdxxcdaddbbbbbcadbdbabadbcaacddbxbxxaxxcacaxdxdxxcxxxxxdaxxaacabacdaabacdaaaacdaaaadbadaaaacbbddadbcdbbadacabadaabcbaabdadbacdadbacbacbbddbdaaaadabdacbbdbbddacbxbaaxaaxxaxxacxcxaxxaaxaadbdxdbaxaacxcdxaxaxxdbaaxbbaaacccbaabacaadaadacbbbadacdaadbbcbbdaccdbdabdbaaacdaaaadabxacxbxbdaxxabaxxxxabbccdbxxxxadaacbxadacdabcdbbdaaddbbadacbdaaaadbdadxxdababaaaaacacdbadbdacbdaacdaaaxaxxaxaxaxabcdbdaabadaaaaacdaaabadadbaaabcdbaadabbbxdaxxbcadxabdaxabaxxbxdxxdxcbxaxbbbxxdxcabaxxdxdxaabaaacabdacaadaadacbddaaaaccdabdbdbbbdbdbabacdaadadacbdaadbdaxxabdaabcxxaxdxaaaabaxbxaxbdaxdacxbaabaaaaaaaacdabbaacacbacbcdxxaxxxaadaacbdadaaabcaadbaaaacaacxxxcccxxxaaxabdbxaxaaxbbaaxxbbcaxxxcdxaddaaxbdbbxbbcdaaadaacxbxabxxaaxaxdxcxacacaacadbaabdbabaadbaadbaadxxxbaaaaaaaabxaaxbxbxbxxbdbdabbbbbadacbdbaabbacdbaddadaccdaaxxxabxdxcddxadaxcbaaacxbdxaaaaaaaadaacdaddbbcabdbbcaaaaaabadadadadaacbacccbaacaadbdbxaaaxdaaxaxxbxxaaaxxacxdaaaadabadbaabdbbaacbxdxxdxbabacdacdabcbdaacdbabaadadaacbdbbdbdxxxxacxadadxabxxaadaxxaadbxcaccxxabxdxacxccdbdxxaaaaxbbabaacacdaaaaabddbbdxadbxaxxxxcdbdxcxbxdabxxaxbxdbaxdacccdaxaxbadxacacdbbxcdbxxxxxxxxadacdbdbbaccbbcbadbcaaxxxdacaxaxaxbxdabxbaaxxbaxxaaxxaxdbcxdbdabdaaabdaadaacadbaaacabbadbacbadbcdbabaabbbdacbaabadbdbdbadadbabaccaadbdabdbcbaaccacbdaaaadbbdabxacdxdaxbaxxxbbdbdddaaadbadacababdaabbbaaabadxxaxaaaacdaadabaaacdbbaacddaxadbacaaadxabxbdaxxxxxdaadbabdaaxxxaxdaaaxxaaxxcdadxcdxaxxdxaabxbdbbbbaaacabdaacbbcacaxcxxaaxxxaaadbdaaacaaacbadbbdbxaxdbacdxbxxxxaaxxxxdbcdaabxdxxdxxcxadacbxaaxxxdaxxaaxadaxaaxbaaaabcaccbcaaabbabdadxcxbdxaaaadbdadbbabaccaaaabaabbaxaxbacddbdbadacdaaadadbacbcxcbxabbdaxxxadbdbbaacccbabacbdaaabbadbdabdbdbabaabbdbdbaadxxacbxaxxabbbaaadbdaaabbabdbaadadaadaxxbaaabdxdabbabccxabxxxacbadaaabbabcaaaabdacadbbaacdbbadadaaaaxacxadxbbxbxadxcxxxxaxadbxbxbaxxaxcxaaxxbabcaxdadxxbacxcxbaxaaxbdxbbaaxbxxxxxxacxbxdxaacccddacdacdaabdbdbabcbxxabxxxadxbabxaxaabxxxbabbxxbcdadaabbdaxbcxddxcxxxbxdaxababdabaxxcdbxaddaaaddbdbdadababdbdabxdxddaaxbdaxdxxxbcbdbadbdbdbabdabaacbabdxdbbdaabxxaxxdaxdabxbxxcdbbxacadacbbdaaabdbbcbabaadabxxbxaadbxaaaaabdbxddxaaxxbddadbdabaaadaaaaaadbaadabxdxcbcxxxaadbxxxbaxddbxxaxxadxdaadacdabbbcbdadbaaddbaaacxaaxadabbdxbxxxxxxxaxxadaxaacdbadacabbdbdbbaabdbcaacbaaabdadaabccabadbdbadacbaabdadacaaadaaaaabdaaxaxbxdbxxxddadbxxdxdbdbxxxxxxaaccabacaacaacdbcdacbadaacbdbacccaaabdbadxdxaxbxbbbxaaxcdbadaaadadbaacdbdaacbddacdaaaxadxaaaaaaacadbbaadbxxabaxadxdbaxxdxaxadxxaxbxddacbaxababxbaaaxbaxbaaaaaacbdbdabaaaabbbadbbaaacbdadadbacbcaaadaaaaabacbaaadaadacddaabacacbbxbdacacdbcbdbabbcadbadaacxcdbddxdbxabxadbxxaabaccdaaaaaabxxxbadbbaabdabcaddabddaaaxbdbdbbacddadacbababaaaabcadaddbbxadaaaabacbbbcaaacdadbaxxxcddbdbaxdxcbaacdxadxbxaaxxacccdaaabcbbdbdabadbabddaabadbdaabdbbdbabdbdabddacxbcacxbbaaabbxacdxxdaxaddxdxxbbxdaaaaabxxaabaxabxaxxaxaxaxbaabdxaabdacacaacaccbacadadbaaxbbxdbxdbxxbxaxcxaxxxcdxdabadaaabbdbbdbbdacabbaxaxbacaabbdxdaaaxcxxxdxdaxxxdadaaxxdaxxxcxaxxxaxbxaaxxcaaaxxdxxdxxxxaaxacxbbaaabddadbcbbdbbdaxadaxcbxxdxbxcbxdxaadxbxbbaxbxxxxaxxacbxxxxaabadxdbxbxdbaaxxbdbbxcbdbdaxxabaabxbdbaaxxadaaxbxxxbaxbbacaacaxxbdaadbbdaabaabbdadacbbadcxcdbdbacababbbacbacbbaaabadbbbbbaaaabaaddacdxbxxxaxbaxdxccxacxxdbxcabxxxbdbxxaccxdxbcxxaxbdaxcxdacdxaadadbbbaxaaaaaxxacxxxxacaacbcaaaabdaabadbdbadxaacdxxxcacacbbbadaaadabbaacadaacacdabadacdaccabcaaaadaaabbdbaxdxxddxxdabadacaadabddbdadbadbacdadxcxxxxaxaabddxxxxbadbxabxdxaaxbxxddbacbxxxaaxbdabaxdaxxdaabaxaaaxxaxbxaccabbdadbbabaacdbabacxadxaxxaadbxxdbadbcdacadbccadaadaxbdxaabaxxbxxxdxdxxaccxccxxcdadaaaabacadadbaaabaaaaacdbdbdaabbdbabaaaadbaaaabddaccdacbdbcccaddbaaaadbabxaaxxcxaxxdadxdaaxdxdxbaaaxaabxxaxxcxxadabdaddbdbdaacdacbaaccxxxxbadaxaxbabbbbdacabaacbdaaxbxxadxadbdaxxaxdxdabxdaxbaaxxaaxabdbacaabbbccbbaaaaadabaadbxaxxxbxaacaxaaxddxaabxacaxxbaadbbdaaaaabcdbdaaaacdbbxxxxcxaaxaaccxxaccbxxbdaaxbaxcbbxaxdxxdbdacbcacbdacadadbadaacbdbbabaaaaaxxxaxxcbdbbadbabadaabdbbdaddadabxbxxxdxbdbdbaacddbadbacbadacdaabcbccacdxaaxdaxbccacxdadxcdbaxxaacdxxxbbbxxxdxaxxxaaaddaadadxbxdacxcdxcddadbxxbdaaadbaxxxxcbxaacabbdaabbdadbadbabcdbabaaaacdbaaacadabaxcdacadacaadabaddacbdaaadbaaadaaaadaxxacdxcxxdxxxaacaxaxxddaaaaababaaadacdaaaaccbbdbbabdbaxacbaaabdbdbadaaaacacbacbabbaddddacadxxaxdxaacdxbdxcxaxcbdaaxxcbxxxaadadadadbdbabaacbaaccbaaaaabadbdacbdbbaadbdbaxxxxxbbdxbacaccdadacabdabaaccdxcbacxbxaacadxcxdxxxcxxddacxdxxbdbxxxbcxaadaaaxbacxacadbbxaaxxadbxaxxxxxdxdaabxddxbxxxxbacacbcdbcbaaaaabacaaaadxabxcdxdxbbabbdbbacbbacaadbxaaaxbxbxxcxadxxbbxcddabdaaaabbdaabdaacbcdacdabdabbbbacbcabbacaaabdxdaxaaxabbaxbdxxaxdxxxabaxxxdaxxcbxabbxcxaxbaxxacdabdabdaadbadacdaacdbcbddxxxxxdbadaccbadbdaabcaabaabadbaacbabadbdadbbdabdaxxxbxdbaxcxbxaxxadadbacaadabdaadbaddbbadaaaaababdbcaabbabbdbacbababdbadbdbabbdbaadaaxxdaaxxaxxxbaxcdxcaxaaxxddxxdbxcaxdxbdabdaxabxxxaxdxbbacaaacdbaddbbabbbacbdbdbbdbabdabxaxabdddxabbxxxxaxxaacxxcxxabxbbaxxabbdxcxbdbabbadddabadadbbaaxdxbaxacxabaxbdabaacaadadaaabddbaxccxaaxxxaacxbxcabbdbadbdddabdadbdbdaadacdaabaccbacxxbbddxxaadxcdxaxxxacbacxxxaxxdxdbdaabbdacabdabacdabdaaabaaabdabdbdadbadaadbdabdbacaaacaaabdbacacaxaaxadbabcxacabdaabcabbacdaacaaccbdbxxxbdbaadbaaacbaabdaacdaaadbbaacdbcaabbaabdbdadbadbdbacabbbddbadacabcbaacdabdxaxadxdaxadadadacacdacaabddaaaaaaaaaacdadbabdadbdaccccbdxxxadacbdbdadadbcabadaabacadbaccadadaaddacbaaxxaabcdadaabadabaacbaabaddaabdaccababcbdbaccacadbadaaadbbbbadaccxxbxxcdxxxxbdaxxdbadbdbadbabdbadaabaxxxaxdbxbdbdaxacdbadacdbaababdaaabdacabdabaaadaadabdbacbcbbbaaaaaaaxxxxxaadaaababbcdadadddbdabxaaxaxbbxxdaxbcdbdaacadbcbcdacbcbadbxxxacxcadacbaaddbadaccdaaabdaabdbbaadacdbaacxbbbaxaaabaaaacdbdabdacddbdadadaadadbdadxxxadaxbaaxdbdxaaxaaxxxdaxaabxadxaxdbxbaxaxxbdabdaacadxbxxxxaxxdaaxabbadbddddaccdacbdadbdadxcabaaadaadadbadacdxdaxaaxxxxxdaxdbaaaabxxdbdbxxxdddaacccdabacdbababbcaadadaaadbabdbdacdaaccdacdbbcdaddacxaaxxxxadxxxxbxacdxbacdbaddbbdabaabdbaadaddbacdbcbbddadabcdaxdxdbbaadxccdxbdxxxxxdabaadbdxaxdaaaadaaaacdbcabaacbdaacdaabcbbbdbaaaacbdbababadabdbaxaadbaxxbaxbxbxabxaaxcxbxbaadabadbadadaccacdbaaaaaadbxaaadxxbbbxdbcdaaxcdxbdaacxaxcadbdxxxxbxxbbacdaccdbadbdbaaadbacbdacdadaaaccaabbdacaaxdxadbacabaacaababbacabaaaaddbdbaadbacdbadbxxxdaxxbbxxdbdbdbbadaabbadbaacaadbbaaadaacacbacbacababdaaaabbbbaccaadadadabcdaadxxaacxdbxaaxaaxxdbdxdxbxxbcxadbxaxadbdadbabbaaabbaaacbbdadabacxbdxcbaxxdabaxxadxxxxbxxxaacddacdbbbdbabcdbdbdaabababbcxbdbdcaaaaaadbdbaaxxacxcdaxxaxxxxxxacbaabdbaadbdbbaccbbbddaaaaacbaaaaaacdbaacaadbaadaaaaccxxxxbdaxbxcxxbabdbxcddaaaxaaacxcbdxxxxxbaxxdxdxxdaxdbbabbacaadbadbbadacadbbacbaaaxxxbbdxaabxbxadbxxcxcaacababaadabbbabdaxxcxxcdaxccxxdxaxaaxxbdaxaaaxxxxxadbadxadbaxxxbdaxbbxcacdxaxaabxdxxbadbcxxxbbxadxbxabcxdxxxbaxxdxacdxaadbbdxbbbdxdaadaxabacxaxxbdxbxadbcaxabxxxaxaacaabadbdadddadbcbcbaxbdadxbxbdaaccdbxxbaabcdbadbdddabaacbbdaaaaadbaadaaabxxddadaabxbxaxxdxdaxbxxbcbxaaxxaxdaacbxxaxxxaaabcdbcdacadaaccaaaadxaadbdaaacbdbcbadaccaacababadaacddbadadaadxxaaaacdabacacaadabaadacdabdacbdabadaabxaaxdbxcxdbadxaxxcaxaxxxbxacabxxcaaxbbdadbacdbbdaababcdabaaabdaacbabbxdxdaxxabddxdbxaxabbdxcadbaaaacdaaaaaaacaabbacdbdbaadabdbcbbaaccdbabacdbbaacdadaaaabddbbbdbdbadbacdbaadadacdbdbacaadacbdabbcaacdxxbcaxaxxbxbbbcbxxxxxabbxxacbxaxbxxxbdbxbxxxaacxaaaxxacxbdxdxaaaabaacaccadbaccdaaadbbbacadadbdxxbxxdaaaddadaabdbdabaabbdabadxacdxcaxbdaxcaxxdxacxaaxaxxxcacadaacddbcacdaacbbdacccdaadddbcbddbdbcabcabadabddxacbxaxbxbxbddaxaxxcacxxadxxxddbddbadaacbaaadbbbbbcdabaccdaaadbdadxaxxadaxbxabdbbadbabbdacdababaxbxadxdadxaxdxxdxaccxaxacdaaaaaaacdabdadbadbbdbdbdbabdaadabacdabdabdaababbccaabdxaxbaxxcxxxdaxbxbdbabbbbdbbdacabbaddxdxadbdbxadbxxxbbcbdbaaacaabacdbadaaadbbbxxdbabdadacddbabdbadacxbacbxxdxxaxbddxbbcadxabadxxxxxdbbaacbxxaxdaxbdbxaxbxaaaxaacxadaaacaabdbacacdadaacabxaxabdaadabadadaaacacdaaadabdbabbcabdabbaadabdbdbxaxadbxddaadddbdbcbdacbbacaaadaacxxdbbdaxdxacbdbdaaaacaadbaadbbaacbdbdbdbdaadbadaaaxxbaxbxdxaaaxaxbadbxaxaaxdxbxdaxbxxaxcxxxxacdaadbdaddbbcdabdaacbbddbacaaacacdbdxxdxaacxbbbdadaaaabdacaaaaadadaxaxxxaadbdxcdaaaxxxxxxbaddxdbbxaadaaaaadacadadaadbbdacacbbbdadxddbaxbxdbxcxxdxxaxabaaaacddbabdadadddadbbcbaaaabdxaaaaabxcbabccdaaadaaaaaaabxaaxbcxddaxaaxxxxaxxxxaadacdaaacdabcdaabacbdbdaacbbdbcaaabdbdacacaabdacdabdbbbbbacdxacaxbbxxaacdacadbbabdaaaacbbaaadadabddxacxdxbxdxcadaxbaaaxdbbaxaaxacbaxxaxxacaxdxxabbaaaxabxacxxbaacabxdbxbdxcdxaxbbdaacdaaacdbccbadbacbacadadaxaaaaxcbxaaabdxxaaxcdxxxcbaxxbxbabdxbdbaxbadxaxaabxcaacaxbbdaxcxxacxxdxcbdbbxxdabdaaacdacbbdabaaaabdadxaaabxdbxxxbbxxaxcbaaxxaaxacbxxacbaxxxdbbccxdaxcbxcddbxxabddabaaacaabdbdaaccdbbcbaabbdbbbacdbadaddbabaadbxxxxaxadxcbdabdbdbddbacbccbdbbaabbcdadxcxxxbaadabdaaaxxxxadbadabadbaaaabdbaaabaddbadaaaacaccdabacdbbbbcacdacbadacaadadbbbacdaxbxxaaacddabaabbacbacdadbxbxbbxaaaabdaaaacbbadbaacdadababdaacaaxbbabxxabcddbxxaaxaxdxadaaxxadadabxxaacaxxadaxxabaxxcbaabdbaxdaadaxaccbbaaxxxxaaaaabaxcbxaaxaxaxadbddbdaccddaacadbabxaaxxxaxaadddbbdbcacdbdbbdacbdaaabaacbacacbdbadbdababbaaaabdaccdbbaaacadddabxaadxadaaxxaababbccaaadabddaaadadadbaaacbxxaxdbxxcbcdbbcxaaaadaacbbdbbcbadabdabxaadbdaacdbcdacdababbbccaccdbabacdbcaabaaacadbabbdabbaadacbdbdxcaxabxaaabaaxaxdaccxbabcxabaxxcccxbaaaaccdbaabcadabadbcadbcacbaaadaaaaadadbbxbaxccxaxcbaxbdadaacaaabdbabaadbdbdbdaxxxbcxxddadaaxcbdacaxaaxbxcdxxxxaxdaadxxaxcbdxbabacdbxaxdaacaadbaaaabbadaxdabaaxadxaxacdxxbcxaxdbaabxbbxxaxaaabxxadxdaadabadabcabdabcbabacbdaadabddbbbdabdbbbabdbcbdaaacdaabdaaadaacdabdabdaacdxdadacxaadxaxbadxbaabadxadaadbaaaacbbdbdadaadaababacadacdbdaadacccbacaaacxabdbaaababacbadaddbaaabxxxccbdxbdbxxxxaxacxxaxdbabbdaaaacdacdabbabcbdabxxaacxxxaxdxxadaxcxxccaxaxaacbddabcbxxxxabcxcbabbxcacxdabxdaaaxxaaaadacdabcaacbcbbdadbdbadbacbabxbxbdacxadaxbaabxaxxxxxxacaaaxxaxdaacaxcadxbxdxacaxbxadxdaxaxacacxbdxaaxxbcadbxxaadaxadxcabbddxdbaacdbbxdaxbaaaaxcxxbxbaaabdaadacxacxxacaxaxadbdaccdxdxxbbdxxcddxaaacdxaxxadxdxabacxxxbxdaddxdxxxbcxdabbbaaxxaxbdbbaaacxxddxaaadxxxxxaxaaxxacccacaabdabxdbaaabbdaxacxbdaacdxaaddxxbcbbcxdbaccddadbadaacaadadbabbdacacdbadaadaacacdbdbbbdabdaaaaabdbaacaaaadbacbxxxddbbdacabaadbcacdadadaxdxdxbcaxacdbxbdaxaaxdxacbdadxdbaaxxcaacxxbaxaaaxdbxdxbbbabbabbaaacbdbddbdadbdaabadbaadaabcabaacadabdbbaaabaadaabcxdaxaaaabaddbcdaaacbdbdacaabdxxdxbacxcxaadbadaaadbdabacdadbbcbbdaacadbbabbcdacaadaacbdacaabadaadaabbaaacbacdxcbabaxaxxbbaaxxaxxxadbdbdadabbaadbcdxxxbxadxxxxbbadadacbaacbbdbabddbaccaadbabdaaaaxbdaxdxxxxaacbacdbbxbxxaxxaxaxaaxaxadbxxxxccxxdbabaadaaacbdbababacddxaxxbxadxcabaxxbcbxxxbbbaabcbaaaadaccbbabacaaabxdxxbcbddaaadbcbdaaddbaababadaabdbbcbbadbaadbdaaaaxbxbxacbdxcxadadaaxxxxdaxaxbaaacbxxbaxxxdxaxxaaxdbdbdbdacbcdaacadbdaaaabdadxabaxxacxaxdxcdaaadaadadbdbddaaaaacbcbdbacacddaaabdacddadadxxaxxxxxacdxdbbaxxxdbadaaxbxxadadxxacxdbbaaxbxxcbaxaxbdxxaxxxaxbdaxxcdxddbdxacdaxxcxxbxabxcdbbaxxbxacxaxcddadbaaabdaddaccccbdaadbacdaaadbdaddaadbbacabdacaaaaadbbadacdadbadacbabddabcdabbcdbacbddbadbdacacxxbaxcbaaaaadbaadbaaxdbdxbdxdaaxxabxaaxxacxxxaxbaaxdacxcaaxxdbdbbxadbbcdbaaaaacdbbbbbaccdbcbadxabxxxaxaxdaaccxxxaabdaaabadxaacbbacbadadabdaaaabdaabcabbbaaadacaxadxaadbbcaabacdbaaadadaacdbbaddacbababcbaadbaaaaababbacxxaxaxxcxxxdacxbadacddbaaabaacabcbdbbdadacdbcdbaaacabdadbacaacacacbdbcadddacbcaaaabddacdbdabaacbbabdaxxxbaaacdaacddaacbaddaadacaaaadbaxbxbdaxdbaacdbbbdaacbacaacaadddadxbxxxabxaaaaxbdxaaxxacacxxcxcdaabaaaxbcbdxxxaxxxbabxxbaxaxbddaaabaxxdbxdbdbabaaccbadadbddadbcxbaxxaxdbaaabadbaccdaaaacdbdadadbabdxxxaabccbadaabdaaabbbdadbadbacbxadbddxbbbxadbacdadxxaxxxbababdbadadbcdbababacaaaccdadbddbababaddbdaxxaxxaxdxadxdxxxxbxbdbcxadxxadaadbaxxxaxadbdbdacadbbdbdbcaacaadbdxdxaaaaxacxxdxaxxdbdxcbbdbacbdadacdacbdaaacdbxxxdxbxaxdacaacxxadacadbdabacbdaadabcacaaacxcdaxbxdxcxdacdbaaadbbaabdacacddadxaxaxxadaccadabdabaadaabdaabaaacdaxcbxddxaxaxaaaxacxbxxcbaxcdxdxxxbddbxaxaaxadaxxbxcbcxbxxxdaababxbdxadxbaaacccdbccaabdbbbdabdabaaxdaxxbdadxbaacxdbaaaddaaababacaaabacaacdbaadacbbdaacdbaxxdaxxxbdxxcacaaaaaaaaaadadabdbaxabdabcbcbdaaaaccddbaxaxaxaabxbxdaddbdxxxcxxxdaxxddbdaxxdaxxxbdbbaabdbcbdaaaacbbxacxxxcdxxdxxccdxdbaaadbdbabdacbdababdbdaacdbacabxxxbaaxdxxdaaxbbcadaaaabadaaaxxxdbxaadbbxcxxxbaxcxxxdbabaabacdbcbadaaadacccbdababcdabbaacxbxxadbaxcxxadabxaxcdxxaxbbdbdxdbddadbaxdxxxbcaxaxaaaxxxxdadxdxadadaxxxbxxdxxxdbdaaaaxaxxxbxaccdaxxabxacdacxbdabxxxdaxcxdxxxxabcaaaaaabaccbaxxaxxbxabadaxabdxbxdxaaxbxxdbbdbxxbaadbaccdbabaabbdbdbacbdbadaccdbdaaababcabaacbaddbcdaaaaacdabdaaaaaaacdbdbaxaxbxabaaxxaxdxbxacxcaxaxxxbaaxbdbcxdbdbaaacaxaxaxcdbaaaxaxccbbxxxaaadaxxxxxxadxaadxxbaxdaxaxacbbdbdxaaxxaxdbxdbxxbdacdxabcxxxxxaxbaxababxxbadbxxcdaxaaaaxbcbdxdbabxxxcdxaaxdxdbxbxxbdaaaxcxxdaxddadxbxxaxadxxbxxadbdxdxdbbacdaaacadbdaabadbdbbdbaabaabdbdacababccdbaacbbdacabdbbxbbaxcdbxxxxxxaxdaaabbdabacdbdbcdaadbacdaadaacaaaxaxxxxdxbxadbaaxbabbadbaaabdaadbdacccdbdacdbaadbadbcacdbdaaadaabaacbbbcaaabadacdabdaaccdaaxxxdacadaaabaabcbdbacbbcbbabadaacaaadbbbdaabxadaxcxxadxxbcxxxdbxbbbdbxxbdabxdbaxbxdadacxcxxdbcbdbacdbdacbccdabdadadbaacabbabxdaxaxacaxxaxbxcdxbaxbaxxaxaxaxxaccbaaaabbdacaaabcabaaxccdaxdxxdxdaxxbxccbxxdaxxcxbxxbxxbxbdaxxxaadxxxcaxbxxadxbxdaxacdbacabdacaxcbaaxcdbbdbaaxcbdadxxxxaaxxddxbdaxxdxxaaxdxabadbaxdxxadxxbxxxxaxaxaadacbbxaaacdaaadbbacaaadbbxdaaxxcxaaccxaxddbxdbxdadbaabadaaaacdaaaadbacbacabdbacdbaabdacbcdbbcbaaxaxdaabxbaaxxxxbbdcbbbdacdbbdaacabadbcdxbxbdbadbacdacdaadabaccdacdaacaacababbacdabdbacaaabdbdbdbaxbdxbxabxddxaxaxddxcdaccabbaaadaacaaadaabaacxaabbddbcbbcadbadabdaaaaccdbacdabdaabaaacabaabcdacbxxxacxdbadadacababaaaabdadacadbdbxaxxacbxaaxaxdbdxdxccbdcbdbdbdbabacabdabacdbdadbabbaaxacdbxbbdbacbxdaaababxacxbadbacbxcaaaaadacbacbdbbaababdaacdbaacdbdbdaacbdacaacacbbcaabacdaabbaaaabxxxxabdadbdaaaaacdbaaaaaacaxacbdadadabdadbacbacacabbcbaaababbadbdacdbdbabbaxdxbabxabdxxxxxaxaaacdabxaxaxaxbbxcxdbabxdxdaxabdxacaxdbbacabaaadadbdacacdaababaadxxaxaaxxxxabdddbxaxxxaxxbxacbxaxaaxaaabxabbbxxabxaxxbdxccbdabdxcabdaxbdxcxdadbbxcaabbcxxdbdadaxxaabcxaxxxxxdxcbxabxxacxxaaxaxbdxxcxbxxbbxaxaabcxbdbdxxxbdacacaaacbdabcdaaaacdabaxaxabdbabaxxaxxcabcdxxxdxcaaxdxxxxxxxbaacacxdxxaaaxxxxxbxxxdbxdbdxaxcxbbdxxbacxaxabacbdadababbbdbdbaabcdabacdabdaxbbxxaaxdbxxbxbxabdaadbxxacxaadxxaxdbaaxbaxxbxxaaacxaxxaxcxxxabaaxdaacxxdxaxdaxaxaabdbaacabaabaadbacabcxxbbxxxxbacdacxxxabbxbddacdaaabbdbdadbadbxbdaacbadaxdacxaaxadbdacbbadaaababdbdaadacdbaaadbcabbcccbcbbdbdaxcbxdaxbacababdbdbaddadbabaadacabcdbxaaabxxdadababbxabdbxdaabacxbabaaxbdadaxdbdbccdacbcaaddbadbdaxdxxxbdaaacxbadbbxxaaaxdxxdbbdbdbaaaabbbdaadabacdacbcbaabaabcdxaxbxcdxaacbbxbcxxbxxbbdbbbxxbabaaxaxxxxacaxxxbaxaaxabxaxxxaxdbaabaxdadxxxbaxcddxbxbdbaddacaaacbdacaddaaaabbdaxaxxcdxxbxabxcaxxbaadxdxdaxbxxxxadbxdxbxxadbaxxadadadaddaddbaabdbabdcxbbadxxxabbdacbdaabdbabacbcddaadacbdbdaddabaaxxxabbxxxbcxxabxdadbbaadbacddaacaadaacbdaacabdadabbacaaaabxbabdadbxaaxdaaxaadbbababcaaaxbaacxacadbdxbdbdbaaadaacaaaaabadbbdacxdxbxbdbdbabdaddbadbdababacbxbxaacbxbxxxaxxdbdacabxcdxaacxxbcxadxdxxbcccdacadaacbcbbbadacbaaxbdxxxxbbdxdxbaxdaxdxxxxaxxxcxbbxxbbaxxdaxxdxbadbxxxcacabaaadabdaabaadabbabacadbadacdbcaadbacxaaxxxxxxbbadbxxdadbxaabxxdxadaxxaaaaabbadbaabaaddbdaadaxbxaaxcaaabcbcbdabbdbabdxabddbxxxdxacdabaxbxxbaxxdbbxcbaxxxdxacxxxxbbaacacdabacbddbaacadabccxcxaccdxaxaaxxdxxaadxxxxxaaxaddbdbcbaabdbaadadabaaccbaxdbxxcbaxdxaxacdxxbbbaacdxxxxxaxxxdxxxaadaadbbdbaabaabaabddbaadddbadbaxxdxdxdabxaxaaxdaxxadbaddxbxxxdbdbdabxacdxaxxaxdaxdxxxaaxxccxaadbxcbdxaxaxacdbxxdxaaxacabababdaacdbaaabbaccxaxdxxxacxdxxxaxbdaadbbdaabaccdbdacabacbbababdaaaaxbdxacaaaaabdbdaadadaacbdabdacbdaacbaaaaddaababdabdbdadbbxxaxxxabbxxdxdaaxaaadaxxxdbaxaabxaabdaaabcaaaabadaaacbabaabdadaxabxdaaxbxxbxcbxbxxxaxxaxxdbdabadxaadbaxxbcaxbcxcdaddadacbaadabadbdadbaaaabdabbcacadxxxxccddbabxxaabxxxadxdxdbcxaxxaacaddxxcxbxxdadaadacbacbabcbbabdaxaacxaxdxbxaxdadxxxdxxaaacbxaxabbcxdxxxdacbbxxabdbbxddbxdbxbxbxdaaxxaabcbdbbxdacdddabcabadbdbcbaaaaaadaabcaxabacbacdbaaadbbacdabdxbxaxxxxxxaxadbacxaaxxaxcaaccbcdbdbdadbaadbxaxxaadxxaxbdbxabaadabdaccdabacbbcbdaadacadabcdabdbdacxxaxbbxxaabxdxbxdbxxaxdaaxaaxxdbxxcdbbaxxacbxdxdacxbxadbbddbaacxxaxxbxxbdababbadaacbbbaaddbdaaaxxxxbadbbabbdacbaacdaacxadbxabddbadxdbxaxadbdxaxaacxadabdxxxxaadbxxdaaxbaaaxxxdbaaxxdbxaxxbdxbbxbbbxababbbcabaabdbbacaabadbaadaaxcabdxbbxdxbadaaabxxxdabxaxdaxxcbaaacbacdacbbababaaaadaacdacxxbbxbbbdbcbabbadadaabdbcbadaxbadaadbbxxxxacbcabaabbacbdaaadaacdaadabaacxbbaaxcabaaaxaxxbaxbaxxdbaxxbdxxdbxdadabcddaxdadxxbxadbdxaaaxxdxxbxbxxbcxabxxxaabxacbbdaaaaadbdacbabdbdxdaadabcaabcdbaadaacdadxbbbbxaxaxbxbbdxxxabcbcbaxbcbaxaxxcdbxaxxdxbxxxxdxabdxaabacadaxxacxxxxxacdxcadbaabadaddbdbdaadadacbdabaccbdaaaacdbaadabcaaxxbcdbbbadacbadbdaaabaddbdaaxbbbxxxadxxcxdxxdxxbxbxcxxaxdbdabxdxdbxdbaabxabaacadaxxbxxaabaaxxaaxxaxxabxaadbaaadbaadadaabdbdbdbbdaaaaaaaaadaaaacbacabcdbabdabdaacbcaaaabdaabdxbabxxbbdabbdddbdabaaadxaaadacbaccdacbadbcaabbxdaxabdbdbxbxabxdxxbadxxbxaaadbaaxdxbxacbaabdbdbddbbbcddbxxxbxdxaxbadadbdacabbddacaabdbaadaaaaaaaxbabxbxaxdxbdxxcxbabcdbcxxaxcxaxcxxxdbxdbbxdabxaxdacdbxcbxxabaadxcaacxcbdxaxbadaxcxbaadadabaabaadabaaabdbdbbdbacbbaaaaabaabcbdadbacdadaddbaaxxxbcdaacdbdbdddadbaaaaabbxbxacdabbcabaxbxdabbdabxaaaxxxaaaacddbadxaaaaaaacbaabbaaabadaxcxxaadxaadxbxxxxxxbcxacabbadabdabbcbabbacbadaadaacdabababbcdaacbbdbbaabacbxcbdxaxbcdxxxaccaaaaaabdbaabxxaxccbdaxbdxacaaabdabcaabbacaaabcbbaaaadabxaxadaaaxdxaacdaabaabxaxbaxdaxbxxxdbdaaacbadbbdbaxxxdxdxxbxdxxbxaaxaxxaadbxaccbxacbbdadbaabdbbcbacdbcdadaababbbabaxbaaxbxdadaxxxcxxacbdbxabxccxxxxxxbdxadxxdbdxdxxaabacabbaddadabdaaadabxcbaxxaaxxdbxbxxaaaaaaabacbaababdbabdaabxxxxxddxaxbdbbxadaaxxcxcbxaaxaxxdabadxaxbdxcbcdbaadaddacaabdabdxxbaabaxadacbxaadxabxxxxxdbxxbbxdacbaacdacddbacdbdabdbdadadadabdbbdbdbbadbdaababaxabaaxabxbcdxdbbxbxaxbadxbxaxdbabaxaaddxxaccdbabxxcaxxxxbaxadaxbbxaxbacdaaxdxxdxxxbaxaxxxcxabacadadabbaaacccacdaaxdaxbxxbxxaxxcdacadabcdbddaaaabaacdbadbadaaabdbadadbdaadabdbbabaxcdxxaaxbxaxxdxxcbdxxbxxadbxxxxdadacaaccdaaabaaaabaxacbxdaacxxxxxxaaacaacbdbaaaadbdbdaabcdbaxaxbadbdxdaxxxaaaxaxacaacbdbdacacacabdbbxxdacdadadbcdaaaaadaadacdabdddabddadabbaabdaxxacaadxdaaabdxdacxxbabaaaaaxxabxccdxxaxaxdxbdaxdxxbcxcxddxaxxxaaxaaaxaaxdbacadadadbadbcabaddbdbabxaacdbcbddbdaccccdacbdbcdacddaabacacbdxaxaxaacbxcaacxbxdbxbaxcxaxbxaaacxxxxbdxaadaadbdaadbbacdbbdabxxaadaxxxadxadxdbadadadadbcdbcabdaabdaacdbbbaababaaadaaacaaaadaadbcbbxxxxdxxdxaxxaaxdbabbxxxcxbdabdbcaadabbbaacdaaacaaaaaccbacacdaacacdbadaadaacabdaadaaccbdbdbaabddbdaaaaaaadacbdbacdbbaccbdabdacbxxdxxaccxdxxbaadxdbaaxxcxaxxxbdxbbxxdbaaaaaaabbbadaadaccdbdaxaacadaaabccadbaadaxbcacddxdbxxxadxacbaaabbbdxabdxxaxdaaacaabdbdaaaaaacaacbdbdbbabadaaxdbcbbaxaabxxxxaxacdbdbdaaxbbbcdxbadxbabaxaxdxbcxaxcbxcaxbaxaxdbdxxxaadxbacaaxxaabdbadbdaaddbbacbaadbdacaxaabadxbxxaxaxxxxacbaaxcxxaxdaabdaaacaadaabbacdbaxdaccaacdacbaaadbaaddabaacaabaacabbdacdacdacabdbdacdaaacbaxbcxxaxdaxaxxbxadxcbbxabxacdaaaaadbdaacaxxbxadacbxxdbxxbadxdaxaadxdxxxbdaaxdbxcacdaaabbababbaddabaxxbaxxdxbdxxxdbbaaadadacaaabdadbdbcbdbdabacaxbxaaxbdxxbadxxaxxabadbcacbdbbbaabdbdbadbdaabbdaadaaadaxaxxdxdaxbabxxaaxdbbxxaaxxxbdxabdxaxxabxxxxbbaaxcdxabadbbxaxaaxaxxxaxbxababdbbddbbcdaaccbcabbdaxabdaccdbxxcxddxxaxbdxaxaaxxxbxxaaaxadxdaxaabxacbdxdxbaaccdabbbaddaaaabcabaabdbdbaadbdbcdadaacabaaabcdbbaaadbadacacdacbdaaabdbcbabaaabbcabdacdacbbdaxxaacdxacxbdadxxxaxxxxdbbxcxdbxbxdadbddbcadbadbdaabaababadbaaaacaacaaadbxxaacdbacacadbdbbaacaabdbabacdbaaaaccdbxbdxbbxaxxxdxxbxdxcxxdbaxaxbbcdxdacbxbbcabxxbxaxxbxabbxdbdacacdbacdadaddabadbdxxcaxxaxbddbxbxxadacbccdabdbadaadadaacacdacbbdaaxxdxcddaxccxxxxbxdddadaababdbaadabdbccaxdxaaxxabxxacbbdababbaxxaaadbaxxxdbaaxxxaddxxcddxacxdbxxbxabdxxxadxabxcxxcxbdxddadxcxaxxbdxxxxxaadbaxxbxxaaxdabbdaaxdabbaaaabdbaacdbaacbccdaddaccbaabdbaabacaaabbdabbdbxdaxxxdaccaadbdaabadbdbbbdbadbbdbddbaadxaxxbcdaxxaadbbdddbdacbaabdacbaaabaabacaaaaaxaaabbxaaaaaxbxxcbxxdaxbbxacbxxxxdbbdbxxaxbxacacxxbxcxxbxbxaaxxbdacaabdbbababdbddabacdxxcbxxxbabddxbaacdbadbddaccdadaabbdbaacaabdbaxxxxbadbbxxcbaxabxaxxxadaxabbcbdaaabaddabdbdaxxaxdxbbbacdbdaacaaacdadbabadacbdaaaabxcdadbbaaacadaabaacadaaaaabdaabdbxbxxxaxxcbdxxxxaaxdbxbdxaxdaxaxbxxxxbxacxcxxbdbxxxxaxxbaxdaxaxbdbxdxdbxaxcdadxbdxcbbbxxxbadbaxbdaxbabacacdbaaacabdadaccbdabxdxbxcacaacaababadbadbdacaabacdacbdabcdbcaabacdbdadabaaabbbaacdadacdaaaddaacabdadaaadbcdbbacbaadbadabbaabaccdbababadaadaabacabxaacacaadbbaaaaadaaabdadbaaadaccaaaaaaxxdaaxbxcbdaacxxccbaxxdacbdaaaxbxbxxaxxaaaxaxxabdbaaaacdacabdbabcbaabdbbadadbxxxadaaaxxxabxbbaxxaxaxbcdababddabddacdbaaadbaacxcdaacdaaaabdbaaxbaaxaaxxxaxabxddbaxbxxbxbdxaaxadbxaxaxxxaxxbxxcxxaccdbaaxxdxbbbaaccaaaabababaaaaabcxdxaxacdbadaxxaxxxxabaxxxxaxdaxaabaacaaaaaaabacaaaaaabdbcdaaaaxxaxdxbcbdxxaxxaaxaaadaaadxacabbdbadaadbcacdadaabcdabxxbaaxxaxaadxabbdxbcxxbxdxbaxacaxxxxdxxdabdxxaxdabaabbaadbbdadaabccabbbdbcxdbaabxabaaxdxaxaaxxaacxaxxaaxdbxxxdxbxdaxaxbxxxdbxaxaxbddbaadxdbxddadbdadacacaabbaacacbdbcbaaabxadbaacbbcaaacccbacdacbdadbacdbabaabxadxxdbbxcxxxdbaxcaaxdacacxaabdxcxacabccababbbadadacbaadbaacbdadbdadbadaadabaaccbcbadxaxxxbxaabxxxxaacxcaabdxxxxaaacxxbxbbxaxxbdbacaabaddaddbadacdaadbaadacbadadacbdaxaxbxaaxdxxxxxxadaxadxxxdabxdxadabadaxxdaabaaaaccaacbabadaaaacccddbdabdacbacacbacaadbcbacbacabdacaaaxaaxxaaxdacdbcbabdaaaacbcdddadbadbxaaxxxbddadacdbcbdbaadabacbdaaabaaaxbdacdaaccccabdaababdaaaacdbdabadbaaacbbbdbcdaabcbaxaxxadaaxxxadaxxaaaxdabxaxaaxxxacxxadadacdaaaacbdadaaaabddabxaxbcdaabaaxaacaxdxaadaaxacdxxxcxbabdxbxabxaxdbxabdbbdabdbaacdadaaddaabaacadaacdabdbdabaadbbdaacaacdbcaabaababaxxbxaxbdadxdxcdxaxcbcxcbaxaacdxacxdaxxxxdbxxbaacxabdxdxxacxaxxxxxxbdbddaadaaaabcadabddaxxbcxbabbadbadbcadaaaaacbdbabacdabcbdaabaaababbbcdbdacbadabcaacadbadbdbdbacdbaaacdbaccbcdadadbabaxcbacacadaababcddbccdbdbdadabdacdabxdbdabxxxacxxcaxbdxxxxbxccxcbaxxaxxadxaaxxdxxxbaxcdbxxabaxaaacbaadacbdaaddabbbacacaadabaaaaaaaaaaadbaacdbxacaxbxaxaxbadxdxbxdbcxbbxaxaxdxbbxxxabaacdaaabxxdaaxxcbaadxxbbaacaaabcdaaaababxacdbabdbbadabdaaaabdxcxxxdacbxxxaxccaxadxabxcxcabxacaxxxdaadxcxxbxcxabbddaadbaadbbdacbbaabccdbdbabddbxaxaxxcxxbdxaxdxcdxxdxxaxbxbaxxxadbdacbbacbaacaadaadbaadabaxxxbaacaxacdbcabaaxbxxabxadbcaabacbabbdbaabdaadabbaabadbaacbdaacdacaaaadadabbaabcddaxcxdbbdaadaaaacadbbbbbdabaadaacdabdaaabxxbaccdbdxaadxbxbdbacabaaaaaaadaadbdbdbbabcabacdaadaadaadadbddadabdbaabbdbaababdaxdacbabxbdaacxxdxaxxadxxaxbdabxbxdaddabaababaaaacadaaacddaxxbxbxccxxxbxxbdxxccbxxaaadaacdacdbdabdbdacdaaaacaaxaxxbxbacaaxxxxaaxdbdbxbxxaacdbdacxbaxbbdaxdxdxaaaxaacxxdbaxxdxdaadxxxdaxaxxdxadxcdaaaxcdaabaaadaaabdabbccaxaxbdbxxaxbababxxbxcadaxbxcbaxaxxaaxaxxaaxxcxdaadbxbdxcacdbcdaabcdbdacbadbaxadbdbadbdaccbdabcacbbddaaacabcbaabaacbabaaaaaaaaxcacbaxdbxbcxxxaacxxbacbxxcxxxaabbbxbdxdxxadbaadadaabcdbbaadacadaxxxxbdaaaabdaabbaaaacdaaaacxdxcdaaxxdbcbxxacaxaaadaddbdaabdbcbaccaaadadbacbabbaccdaabcdadaabbdbbxxxccxdabdaddbaaaaaabdadbacdxaxcdaxxbacxxcaaaxxaaxxcxadaxaxxdbxxxcdxxxaxbdacddaaabbaadaabadbaabbdbaacbddxbbbdbxxbdbddaccbacaabbadaadacaabadabdaccbbbaaacbdaaadabadaacaxxadxcdxxdadaaxdbdadaxdbddacabbaadaabdxacxaaadbdxaxdbdxdaxaxcbxcbxaxxaabacdbbadbaabdbbdaaaacadbaaaadadbbcdbacxadbaadxaadbxcbaxaxaaaabaaacaaabddacbaabccdadabbbaacacdaaabbbaddaaaaabdabdaadbbaabdbbddaaaadbbdabbbaacxxdbdabxxbxxxxxxaxaaxdbdbbdxxcxbxaaxxdacxdbacbadxxaxxbabxaxxdaxxaxaabcadxaaxxcaaabbxdaxxxcbaaaaaaabacaaaxbaxxxxxxbxxbdbaxxaaxcacbabdaaaabaacxaxxdaxdadbaaabddbadadacaaabaxxabxbacadaabaaaaaaadaaaadxdxcdxxaaabcbdbdbcdadbbaaaabdbadxcaxxcaxxxaxbbacxbdxxdacdbbdbdaxxxaxxadaxxxbdxxdddxddbbdacddabcaadbaadacbxcaacxxxdaabdaaacbdbdbdbabdabacxcdxxbxaxabaacdbabdabadadabdbdaacbbbdaaacadaaadaxxxxxxxaxdbxxcbabxcddadacaaaaaabaxxxdxaacaxxxaxddadadaadbcacbdbbddabxacdxaacxxxxacxxbdxxxxabdbbaccbxabbbacdbdbbdbxxdaaxdadbbaadxxxbdaxdabacbxxxaxdacddacdadadacddbaadadxxxxcbxcdxacaaxacccbaaadxxcxxxbxaxxbaacbdaaabbabcdddbdbxxcxxdxccadacbcaaadbbaccbdaaaacdaacbdaaabaabacaadadbdbdabacbbdaaxbdxaacbdbxxbxxxbaxxxxaacbbabbbacbbaadaccdbdbbbacbaccaaaxxdbccaxaaabaaaaacadbdbacdbcdacbxdaxxdaxbxabaxxbbxxxxdadabaaaacaabaaaaaadaaacdacdaxxxaxxxbbxxxxxxbaadbdaaccdadadacadacdaaacxdaxaxddabdbbcbdabdacdaaabaxdaadxbbbbdbacdaacaxabdaadacbdbddaacabcbcdbbbabadbaxddadxcbaxxbcxxacccbabadxbdxxacaaxabacxaxxbcxabcbbaaxdaadbdacxbxxxxbdabacbdacaabaaacdacadaabdcccadbdaacddbdbcdbbbxcabcxbxaaadaxcxaxxxbxxxaabbdbxxbdbxdxxaacxxxaxxbadaadbaaaacbbdadaababaadacacbbacdbdaacacdbdbdbbdxxaxbddadbcdadaaccbaaxxadbbadddaaaadadbbaadbaxxaxdbxbbxxxbxxaxaxaadaaccdacddbdabaabaaxbxxabaaaaaxaxadxdxxdbadaxxabxdaccaaccdbdddacbadbbaaacbbaaaccaxxdbbxxaxxaabaaaaaxbxxaxcxbadaaaabbdbaadaacddaaxxaxxaabbaxxabdabaadxdacabbaabaaaacdaaaadbbbdbdaxxcbbbabdadbadbaacacxxxaaaxcdaccbdbaacbbbcadadbaacdacacaxbxxxbaxadabxxxdaxdbbxbbxbxadxxbddabxxxaabadxaxxxxabxaadadaadbacbaadabadaadxcxxbcxxccxxbxdbaxdxaaaabbaxxxxxaxxxxdxadbbdbbcabcaababdbddabacbbbaxdbxbxxxcbdbdadaaaxdxbdxcxxbxacxabcxxadxabbacxxdxxcxaadabbdbdabacacbacaaadaaababcbdbbacbadbdaadddxxxxxbxaaaaaxabadabaaadaddaacaacddbabxdxxxaxbabcbdabcdbaxaabxabxabbbdxxbbbxxbadbdbbacababdacaadaaaaaadbddbdbdbaxaabxxbdacaabaabbdaaaabbbccxbxabaaaabaaacdbddddbdxxbcaaadbaabbaaaxaxcxxxaaxbcacdxaxxbxacxxaxbbdbdxdddaacdbaaaadaabdbadaadaaacdacxbbxxbdxcbdaaaadaaadbaacaadaddbabbcabaxbdxcacxdaxcxdbdxaaddaxxaabxxaaaxbxxdbacxaaxaadbaadadadbcacdaadadbxbaxxcaxadxxcaabcxxdaaxaddacbcdaabbxbabdxdbabxxcxxxxxbacbadxxaabdxxxdxaaabdaxaxxxacbcdbadaacdbabdbaacacaaddxdaaxxxxadadaxaxxabdaxxddabxaaxxbacbbdaddacbdaacbaaxacxdxdaxddbxaaabaacbadxabxxxxxaxcdxacbxabdaacabdbadbbabbaacdacdaaabdabbaddbadaxxbxxxxxacbdbabcadbcbbcadacdacbdaadbacdaabaxdxdaxaaxbdxxdadbaxbadxcbaaacaaacbdbabadaaaaaaxbbaxabaaccdabaababdabdaabdadacdbacaabdaadabbdxbxxbxdxacababbdabcadadbbabacbdabdaaaadbdaadbdxcbdxdbxadxxbxaxdadadacbxadabadaddadbbaadbdadababdacdddabbcabdbcabbbdacddbdaaabdadaxacdxcbxcxcdbcaaddacaaaadadaaabdaadbaaacadaabacbdabbxbbadxxabxaaaxabaxbbaxdxxxxxxaaaxaxxcbbdxbbxbbaaaadabcabaxxdaxxxbdaaadbdbaaccaabcbadbabdbcbcdaaabdaabaaacdbbbddbacadabdabbdbcaddaaaacbbacabddbacbdadbcaaaaacacabcbbacaabccdaabcdabdacadadbxxbxaxcaxaaxxxaaxxdxbxaxcaxabdaabababdadadacaabdadadabaaaaacbbbdabbdbdaadbdbcacbaaxaaabxaxdadaaxxdxxbxadxxabxaadaacxdaxadbdabdababddadbaaabdaadacdbbbabdaaaaacdabaacbaaxxxxxadacaxdxacxadxxxacbaaaacdadabbbbcddadbbadadaccaabaccbxcxbaadddadadbcdbadaaabadabaabaaabaddaaaaaabadacacababdadabdbdaaabdadadacdbcdabbdbabxdxaxbxdbbadadbdadbbbdbbbacbaabacbacaaxdacxxxxxaxcaaabbaadbacadacbbbddaacacdbaaaadbdaddaaadadababcdabcaaadabbbdbacbadcaaaaaxxbaxbadadabcadbadbadababbaabbbaaadbabbbbbaxacaxdaxxxbaacbdaaabaadacbdaabadaabdbdbabbxxbadbdabxbdabbxxacxaxxxxxaaaaxdxdaxaaaabdacbaacbcbaaadaaadxadxxbxbcbddxdxcxaadxadxadxaxcxxadbdaxdxabxxabxbxxadbccxxbcbxdadaaadbbdacacaaadabbdaaabdbdbacxxccdbxxcxxxbabaxbxbacxdxdaaaaxxxxbxdxdaaxxdxbxabxxaxbxaabxbbcxccdabaabdaacbadaacdbcbaaaadadadabdadbdbbddabaadbdaabaddaadbcadaaabaacbdaaxaaxcdbacxbacxxxbdaxdxxdaxabbccaaaaadaaaaaxacbdbccxaxaacadacdxaaabxbxaxxxxbxbxxxaxaadaxbaabxaaadxxxabdxacxbbxxxbxxdaxxaxbxaaadbaaxxxxdbbbdxaacabacbdaabacacdbacaxdabxacdxaaxadbxaxxxxaxdaaxxxacadaacdbaadaadbbaabcbaaxxxcbaacxdxbxacxxxxaacdxaxcxxcdabxaxcaabacabdadacacdadaacdaccdaaaadaddadbcaaaacddaccbbddaadadabdbdabdbaadadaadacbcdaaaddaaadbbadabxbdxxbaxxaabadaaaaaacbaaaccadbdaadxxaxxdabbcdbxbxbaabadadxxxxbcxddxxbxdbaxxxdxxxdaabbbbdbdacbdxdaxxbcdaacddxdxbdxxbccxxxaxxcbadacdaxxaacbdaaaaacaacadacbdbdadbdadaxxxaaxdxxxaxxxaxbcdaaxbxxaaxdbbaxxbddaccdadaxcbadaaxcbbbxdaxxadbbxdxbaacbbaccbaaaacadaadacaxccxxbbxxxaxbdaaccdadacaaddaaacaacaaacabccbacaaacbabcabaaabbdacdbbcaxbxxxdxdaaabacxxdadaabdabaaaaaadbabdabdabbaaacbbbbdaabdacdadbaadxcaaaaaxxdbadbxaabadacxaxcxdxxxxaxadaadaadxbxbaxabaxdabxbxdxaxbbddacbaadaaacdaacdadbdbadadacbabadacadaadaxxacbxcaxxbaaaxbxaxxcdbcxdaadaabbaaabbbacdacdbccaxxaxabaccbdacdaaabdbbbdbbdbbbxaaxdabxaxxxaxxdaabdbbadbdbdaaaddbdbabdbaccbaabbbacbdbabacbdbbbcddaxcddacdbdbdbaaadbbaxbacaxdacabdbbadaaaaccaadbdaadbbabaxxxaxcxaaaxdaacxaaabxcxxcaacdbaacacaaacdaacbaaababaabadbbaaacacbdbaaacaaadaacaabaacxaxaxadaxaxdaxxdxxdaaxxxddaabcdbbbdaadadaababadbbxxcxaxdxaxaaxcbacxxbxacdxaxxcbdxbxxxbabdbdacbcdabaabbaaadaxdxdaacbxxxabaaacaacbdabdbadbacbddaadaccdbaaadadacdbadacbadbabbxxxdbxxdbbxxbxcxbbxbxbacdbdbdbdbadbababcbdaacadaddbacbddaacdbcabaxxdxadaxxxxxaaxbbbabacabdadbbaabbaacbddacaxdaxacxbdaaabdaaaabaacaadaaccdacbdbaxxxbaxdxxxaacxdbbaaaaabdbdbdadbdaacbabbdacbbbacdabdbaabdaacbaadacaadbdxbxxcbxbacaababdacdbdbcabbdbccbdaaaacdbdaaaaaaaacdbccaadxbxxbdbdacdacbbadaabdacddabaaaacbadbcbxxaxdaxbdaababbdaababbaddbdaaaxdxxadxaxxxdxaacaaadbdbaacdbaaacaadbadbxcaacbabxaacddxaaxbdxxxcxxbdbaccbdacdadbbbaddadabacxaabdaadxbaxxxaaadaacdaaacbcdbcbadbabacacbadaddbdbbbdbdxxxdadbdabddbbdadacbbbddbabcaabacadbbbdadbdbadacdaacxxaaaadxadxxaxabadaddbdbbacdbdadbaabbcabbcxdxaxxadxadaxxxabaxabxadbxabdabxaadbdxcxacbcxabdadbxbaxabxxxcacaadaacbaabaaaaadbaaaaxbaxdabaaxadaxxdbaadbaabbaabbaaccabbdabdbdbabaaacadaaaaxaxdddacaxdxadbxcdbacaacaabaaaaadabdaxxabxxdabaacdabbaaaacadacaaacxbxdxxxabaxcaxxaxaacdxaxadbacdbabdaaaabaccdbabaadaabacbbxacdxxaccdbxxxdxcdxbxbaxaxxxcabdaxxacxxdxxaxdxbbddxxxbdaadxbxacxxdaaaacbcabdaabbaadbccddbadaaadacbabdbdadbaadaabdadxbxxxaxdbacaaabdbaaccdabdbbdbaacbdbadacdbaaacbdacxbxxxdxcxxabxdbcdbbadacbdbdbbdacbdabdbbdxxacxadbaxxaacdbbdabdbcdabdaaacdabdaaacddbadxdbababdbxxxbcdxcaaadbdaabaaxxaaaxadbdbxaxaxxbaxbxdxxxbxxxbacbaddacbdbddbadadacaacbxxaaxcddaaaxxaaxbxbxxxaacxxxbxdxdbxbbxbdaxbcbdxxxcdbaxxaxdaxcxababxxdxdbadbdxaxdadxcxaxbdbdaabaabdbbaaabaaaxacbxcbxcdaabbadabdabdabdabaxdbcbaadbdbdacaabaxxxaxxdacxbbdaadaaababdaaadbddbaadacxbaaxxbxbaxxabdddaxdxadbbbaccbbbacacdbacbbbabbadbdbcbaabcbbbadaaxbddaaxxabcbcdaaadbacdaccbbaccxdxadaxdxaxbxxdxxdbdxaaaacbxxxaaaddbbdbcaadbdbdadbxaxcbbdabaaaabbabdaadbbbadaacdaabdaabaabadbxaxxxxxabaxddxxxxdxaxcxxxaabaxaxdbxbacxaxaxcbacbxbacxaaxaxxxbabaxxabdadxaxaaxbadbxxbxbxdxdbaacxdxbbxdaaxaaxaxabdaxbdxxcdxxcaxaaaaadbabdbaabdaaccddaaxbacxxadxxxxbaxaxaxxabcdbxdxxxbaddaxxxbxcbaxxxdbxaabdxxbdabdabxaxaxbaaxbdaadacaaccdacddaabaaaabdabaxdbxcxxxxxbxccxadaxbxaxxxbdbxcbadaxbdaxxxbddxbxxbxdbaaaaxacbabxbxdacbaadaabbdabdbdbbcdababbadbaabbaacaadbbdbxaaxdacxxaxadbbdbdxaxxxaxaccbbxxxxbddadxbaxdabaabcbxdxaxdaacdaxxxxaaaxcxaxxdaabaxbxadxdaxaadadbaaxxxbaxaxcbxbaxbaxxbxxxbaabababbabdacbdabdadaadaadbbaxdxxxaxdbxbacbdaadaaaaacbddabbdacdbdadbaacaadaacaddbadbaacadabaaaabaabdadaabaacdxbbxbacxbxadaxdabaaaaaacbbaabcbdadaxdaxbxaxaxaxxdbdbababadbcdaaababdaaaaabdadaadabadbdabadaaabbddaxabxaadxxaaadaxcdaxxdxdadxaxxaxbdxbdacdxxbxdxcdbdbbdaadaaaacdaaabdaabddbxxaxaaxxcxdbxxadaaxdxxadbbaabaccdbabaacbaccaddbbaabcdbaaccaabcdadbdxadbaaxxdxbadxcxcxxxcxbxbxaacxdxaacdbdxacxxaaaxxcxbxabxbxdxxxcbxadaaacbbdaaaaaabdadxxxxxxaaxaabaaaaacbdaabcaaccaadbacdbdaxdxcdabdxcbacacbcbbddababddaxacadacccdbbbabdbddbaaacdbdabdaaaxxxxxdaxcxxdbaxxxxdbcbxxaaxdxbxxbdbaabcdbdbaacacbbabdaxdaaxdbxxbxxaxxadacbadaaaaaaacacbxxbabdabdaaaabdxcxxxxacadbacadbxxxbaxxbxcbcbbabdacaacdaaaccdbdabdbdbaabdaacaaaadaabbaxxbxxxdaxdxaxxaxacxdaacadbacbbdbadaaabaacdacdaaabbdabadaabaaaaccdbabdaabdaadadbbcdaacdaacababacaaadbcbbaaxbdbxbddxaacxxxadxdbcbbaabxbdacdbaacbdbacbaadadbdbacbbcbabadbaabdaaaababadbbaccbdbbxaaxxxbxdaxxcbadbdbbdbaaaaacaadbbbdabdaaabaaaacbddaacbdbdabdaabadbaaaaaabaaabaacbdbaadaacbddaabdxdaaxxbxaxaxaxacxaxxdacdbdddabxaxaxxaaxcxaxxddaxabcbaxaxbdxxxbcadxacxaaxdbbbaaacbdbbdbdbdbbdaabaacabbxbxxaxabdxxbaxdaxxacdbaaxacxaxdadbxcxaxxxbabaabxdaacaxbxaxaxabdxaaxxaxxaxdbdbaadbdaabbbadbbddbaaadacadbacababbbaabdxacadaadaacacccdbbcdxddabbbbaaaadadaaabxbxdaccaaaacbbacdacabdbabbaacdbdadbabbcbacbxaabdxxxxadxcaabxaaaxacxadabaabadbdaacdbcbcdaxbcbxxbxbxxxcbaxaxxcbdbaxdaabcdabxaxcxxbdxabdbbcdxaxddaabaaabaacdbcbxaxxxcbdxcaxcxxacbdxxcxdadaxcxbccxaccdxaacbabaabacabacdaaccddxxcxxaaxaxxbxxxdbxxbdxaabdxcdxxxaxxaxbacxxaxbxadxdaaxaabxbbaxdxabxbdabxbbxacxdbxxxaaxaxxxxabxdbbbbdbacabadabbaabbdaccbbxxxabxxxxxxdacbcxcxdabxaxbxdabacdaxacxcxdaadaxxacbaxxbdbdbdacbdbaddadaaaxxxxbaaxbaaxaaxxbbacadxxxdxcxadaxbdadxxddbaxbaabxbddaaaacdaxbdaxxabdaabxbddadaaaaabcaaaxaxaxaaxaxcaaxxxaaxaxbxaxxacxdxdxxxxaaxabdadxxaxxbdbdaadbbdabdaaaccabaabdabdaxaxadbdxdadadaaxxxaaxcacdbxaaxbaxxbxaaxaxxxxcaxdxbxxcxaxaaxxxcbbdaabdabbaadaddabaaabdacxcxcxadaxbaxaxbdbaacacbdbaaaaabcdacbabcaaabaadbabaaadaadbdadadxxdxaxbxcdbaxxxaadbxaxaxdxbxbxxdxbcbxxdxaacxxbxaxdxaddaxaaaxxxxbxdxxxaaaaadbbdaaadacaddabdbdxxdabbcxxdxdxdxaabdxxxxxacxaacxabdbdxxaabxxbdbcaddxabaxxbxxdaxcxbxxxbdxbbbbadaxxaxxxddaaaxaxaxdbdaadacadacadbababcdbdaadbbdaaaaacbaabddaabacaadxxxxbdxxaacbdabdadbabdaaacbdaabxbacxaadaacaaaddbadadacabaadaaaaaaadababbdbbcaxxdabxxdxxbdxaadbdxxaxbaxxxdxcdadxxaxdaaxbaadbxbxacxaacdadaddacaadabddbaadbdacbbadaaaxaxaxdacdabdaccbaabaacbaaadaadbabcbbbbddxxxdxxbxbbaaaadbabaabbaabdabddxbdbaabdbdabdabdabdbaadacbdaaaadabdbaaabadxcdacxxxdxdaaxxxbxbxdbxxxaxccaaaaccabadbcbadbbdaabaadxbabcacbadababdaadadbdbbcbcbbbacaacbbbbdbdaaccbbdacdaaaxaxbabaabxxxacdbxxxaaxxxabaacdbdxaddxaaaxcxaxxaaacbadaabcdbbbaaacaabcdaaaaadbdaaaadacaadbxxaxxaacbbdacaabdacbaacaadaddacbadabccdabcdaacdadbbbaxbxxxbxdbxcxbcdbxaaxdacdaxbdadbaxababaxbaxaaaxxdxbdxaxaxcxbcdaxcaxxbbababdbaacbbdabdbadxacdacbaaacbdaacdaccbcbdabdaaababdadacxdaxxxxbaxabxxxacdbxxxaxbdxdxdxabcaddxabbbaabadxbbxbadbdaadbadbbaaacbadbbdxadbxaxaxacxdxaaxdbadacdadaacbacbcddaxxadaxdbdbbdbbbdaaabbbdadacaxaxaaababbcbaacdaddbadbdaacdadbaaadbdacaaaabbdbdabbdacbaadadadaacacaacdaadaadbaxxacadbaaadaaaaabbbbdbabcddxaabxxdadxddbcbbaxxxxxdbbacbdbaaaccdabbadaabdbaxxaxxdacxdxxddbxaxadxxxbxaxcacabaaaabaaadaaaadxacacabxaxxxadxbcaxbaxxbaxccxbadacxbxcbaxbxbbaxxdaadaabadaaaacdbbabaddbcaddaaccbaccacbaacabaaaaccadbaaaabcxcbbabbadbaabaadbaaadadaxdaaxaxbxbbdxaabdxcdxacaxxddaxabxbdbxxdxxxxaxcddxcxddadaxxaxxbadbxaxbxcxcbaacxbdaabadadadaaadabcbabxxxxaxxdaaxcadxcdxaxdxxbxbxxxaaaabaaadbabaaccdacbaadadadcbbabdaadbabaadaxxbbxxabxaxcdaaaaaacabdabdbaaaaaaacabbbadbbabdbcbdaacdadxabadbadaaadabdaacbabbadxxbaddabacadbcacbacababababaacbdbacaaadaaacddbcxxdadddabacadacdbdadbcbcxxbxbxaxbxaaxxcbcdxaacadbdbacadaabbcadadbbxxdbdbcabacdacbacaaaaadaaxcxacxdbaaxdaxdbbadbacadbdadbbababddadbadbbaaadaxcdbxabxbdxaaxxxbxxcxaxbacaxcbaxaaxxxddabdbdbddaadaadabadbdadbaccdacxxaxxcdxbcxaaxdaxbbaxxaccaxxxbaacdxddbxxxbxadxaxxbaaaaaxdaxaxdxdxaxxacxaaadaabadadabadadbdabdbbxxxxbaxdbacdxxdbdbaaxcxxbdbdbdxxabcbdabdbbacadbcbcbbbbabaabaccdaxbxxcaaxxxxxbacxxxdxdxxbdxxaabcbadbdacadbabaaaababxaxdaabaadbxxaaxxbdbxdbabacaadadabbdbdaxcbdxdaaabcbababdbddbdbbacbbaddadbbbaacadbdaabaddadbdbacxcxxaaaabacdaaabababbbaacxbbaxbxxcddacxdaxaadbxxacxbdxabbaaaaadaacdaaaaabaadbaxxdadxacxxxdbaabxxdxddxaxxdxadbxadaddabdbadaaacdacaaxaaaxdaxbcbdxbaxaxxbbdxxxxxbaccabcdbdadbxxadbdbxxdxaxxaxbaxbaaaxbcbdbabxxaadaxxadxdaadaacaaacbbacaaaaxbxxaxaxabdbdbbbadbabdaaaabadbcadadbaadbcdacadabacdacbbaabbaxxcxxbxaaxxdacbbdbcbadbaaaacacadacdaacdaacbddaxxcxxbabddxbdxddxxaxxxxabbacxaxxaaxbxadxaaaxxaaxabxabxacxxxabacadbbadadbdbbadbaadbbadbaabcbaaaaddbbbcdaadbbdbcaddacdbcadacbadaabaaxxdbxbabxxxaaxxxxacdxxxdxxxccdxbdxxxxdxxddxaaxxaxxxacdbxdbabxxbxxbdadxcxxacaxxxaxaaxcaaxxaaxbxbxdxaaaxxxaxxaxbxaxbdbdxaxadaaddaddabaaaaabbdabxacxxdaacbaaabdadacbdadacaacddacdxacbdaabaabdaaacbadaaaacbdaxxxbxcaabbdbdaababaaaabaadabddbbacaaxacbdbdaabbddaaaaaadababbdbccadacdacaadbdbaabdaaadxdxxbcaadaccbbdadbacabbbdbxabdxdaxaxxbaxbcxbdxbbddaxxdxxaxdaxxxxxabbbaabdabaaaxxcxbxaxxcxxdxaaaaaabaacbadbdbacaacbaacadacbdbcbbaaaaxacxaxaxxxacdadbcdxdxxcbbaxxxbdabadbbdbaddaacbdaxdaaaaaaacbcacdadbaaaacxdbaxbxxdacxxbaadaacccbbddbdaabbadabcdacbxaadaadbaaabadxaadxbxbdaxcbbbabdaaaaabaxxxxcdxxaaaxdbxddxxxdbadaadbbaadbdabbabcdaaadabaadacbacadaacbadaaadbbxcbaxxxbbxxacxxbxacacxdbaxxcbdaxbxcdbxbcddacdxxaaxxababaadbacabdaaaaaaacdbdbadaaabdxdxaxaxxacbadbadbbcbadabbdacbdadacbbdaababaacaaadadbdadabaacbaaaacdbddadbaddaadbacdaacbacddaacaabadbcacbbdbadbccbacacacabaxbbdxxxxbbadbacbadbabcbaaabaacxxbbaaabaaaaaaadbabdaadbadbacabacacbdacabdadbdadaxdbxxaaxxddbdaacacbdadaccaccdbdacdbaadbadaaacbdaabdddbdaabcaabadbacxxcacabaaacabdbacaadbaaadabdaabdbacddddbdbcaaxbxxabaabbcdbaabdacaadbbbcbaccadbbbacaddacdadbadadbaadaxaxbxaxxdabaadaxcbadbcbxxaccbdbadabdxxcxccaaxxdxaaxbbbccxxbxabxabxaxcxxdadadadaacdadadbbacdbadaacxbabbddabadabcaaaabaabbdabdadbdxdxacxbxbxbxbacbxxxaddaaxxabbaabdxaaxbcbxbaxcabdxdxdadxbbdxaxdaxcdbcdxaaxxbaaxxabdaaaxxdaacbdbbbdbaaacbabddaaxabbdxxxbxxxacxxbdxdxxabdxxaxaaaaadaaabbabbabdadabdaaacbbbacdbbdbacaacdbdxxbdxbaxxxxaaxbbxcdxbbabxaxababbaadbaacbddabacdbdabdaabxbxcbbdxxxxxbbadadxxxxxxaxaxxdaxadbxbacaxbxcxxdxdxxaxxxxdxcdaabddadadabadbaaabaddbddacbaxxbxdxaxdbdxcaaxxxxxxbaaxbcxxxxxabadbcadaaacdaadacabdaacdbdabdbabcaaccbdabdaaaacbbcaacdbdadbaabdaacbadaadbdbdxdaaxxxaaabcbdbxdxbdbdbbaadbdabaacaabababxxabxdbbdxbxbaxbxdabacdaabcddadbbbacdacaacxabcbxxdxbaxcxxxxxxbbadxxxxaxbdaxaxaaaacbdaaacaacbdbbcadaadabaadaacdbdacxaxaaxxxdxbxcdacbadbadbbbbaaacdbbdbacbdbdabbadbadabbdbbbdadacdbbacaxaaaxdadxxxxdxbxxbxbcxbaxcxxxxacdbaabdbxaaaaadacaadbadbabadaadacbdacbaxbxxxxabdacdaxxacacacxdaccxaabcacaxxbbxaxdaxacxaaxxxxxdbxbxxaxcdbbdxxacxxxbbxdbacadaaaccbaaadaadabcxxdxaaabdxdxxxdxdaxxxxacxcbbbbaxaxxxxbaaxdxbxxbcxxxaaadbaxxdxbxdadaadbxxxaaabxxxxaadaacdaaadbabadaddacaadaadabbdbdadaadbdaacaaadaccbbbacdbdaadaaxaxxaxxxdxaxabcaxaxbcacdxdbxbxcxaxxcxdaaaaaddaaxxxadbaabdbabaabcdacbaacadabcaadbcaadbadadxxdbbdabxdbdxaaaxbxadaacxbdadbbaabbaaacaabaaaadacdaacbdbbaxxxbdbdaxadaxxdxcaaaxxaxacddbdbbaccaccbaaaaabcaxaadbbbdbdbdbddbdbaadbdbbaaaxxaxdxxaxbbdbxaaaaxacacccdbxbbabdaxxxcadxxbacxxxbcdabacbbadaadadbabbbcbxxxxcbxaabxxcabxdbxbxxxdbxxdxcaaxxxbaacddacdbccacadbcbdxaxaxdbddadxaxaxxbaxxaaabaaacdbabaadaaaacbadbacdadbaxcadababaabadaadddbbacaadbbacaabcdbbbdbbaabbaadbababdbbbxdbxbcaaaxaxxaxbdxaxdaxbxxacxdbxcaabbcdbbadaaddbbbdaccdxabdadaxxdbaxxxadxaxxabxxadadxcbxbxaxddbxxacdbabxxadacdbdbaaababadacadadbdxdbxaxaccxxxdaacxxaxabxdaxaaacxbxxdaaacdbabacacbdacbdbaadxadbaxbdaaaxaxxxxcxabaxxaxaadxbbxxaxbaxxabxxaaxxbdbxdbbxaxxbadxaxcaxxbxaxxdxxxdxcacbdbbadbaaabadaaacabxxabxaxadbaddaadxxdxdbcaaadaabcbbaacbacaababcbababbbacabxbdxxxxabddababcaacbbdbabbbdbaadaaaadbbacbcbddadbbdacdbaacdbaaaaaacbdaacdadbdbdbaabxcxxdxxxxxddxaaxacxabadaabdbacdaadbdbdaacacdabxdxdaadxxdxadxxaxbxcxxdbaxcbaaxcdbxaxdxxxaabaxaxcadaaabaxaxbcxxcxdacaxxxxxxxxxadaabbcxcbxxbdadabxaxxxxbcxxbacccxbxxdxbaxdxxdabbxadbaacdacdbcdacadbdxccdabbdadbbaaabbdaadbbbbaxdabadbadbdabdbbbaacddaadxacdaaabacacacbaababcdxxxcaaaaaxdbxxxbcaabxaxxbdxxadbxxdaaxxxxxdbdadaaaxxxdxaxxdaxaxxxbxxaxbaxcbaabdacaacdacaacbbadbdbacaxaxbbbxxcxdaaaxabxbxacbxxaxxxaxxxaxcccxadaxxaxaabdxdbddbdbbdabdbdaabadadbbadadbaxxxxxxxadbaxaaaabadacdaaadabdaacccddacaaaadabdxcxxxaaxbxdaxcxacaxxxbabxacdxxabxcadxacbdaxxxddbxaaabbxdbaxdxdaxxaacadaxdxabcacxddaaxxaxbbxxabcxxxxadaxbdbcxxxaxxxdxxaaxdbadxaxdxdaacbdabaaadbdbadadaxbbxxxaxaxaacxxbdacbbxaxxxcxdacbdbdaadadaaadbcdbbddbdaadaxxxdxcxacxdaabdaxxxxbaxdbdaxaxxdxdbbdxaaaxabddbbdabbbcaccbaaadacdaaadbdacacadaacbaaaxxaxdxxbbxxxxaaxaaacdxaxxdbcbddbabdadabadaadadaacadadabdacaaabdaaabaaaabadbacbaaabdabdabdadabdacdbcaacdaaaadbbaaaabdabaaacxxcdxbxacdaxdxaabbbaaabdbdbaabbdbbddabacccaaadaaaaaacaaxxxxdxaddbxxxabcaxaadxxabaxbaxdxdbadbxxxxxxxdxcbdbbacdacbdaadaabcadbaabdaaaxaaxadxaxdbbaxaxadxxbcxxaaaxabbxcacaxcdxxacaadbbbacbadbaaacbdaabbxxbdbbxxxbxddbbxxcbdxxxxbxdxxxaadacabacbaabaacbacdacaaaxxxxaxbbxaaxaxbxdbbaaadaabddaddbbaxabadaxxabxdaxxacaxxcxxbxbadaxdaxxbaxxcxxxxxaaaxxbdaacbaaaacbdabdbaabaadacbadbccaacbdaaacbcacaadbaaacdadadaacaabdbccdbaaabbdaabaddaabbxbxxxxxadxaxbaadaadaaadbacdadaabdaaadbbccdbadaadbabadadadaadadadaaxabadxaacxcbdaadbdbdbacaabacdxabcdaxaxxaxxxxbxbxbbaxcdddadaaccacadbdabaaacxxxaxxbadadxxdxabaxacxaabddbbbdaaaadaabbddbdbdbaacbcbaacxacdbdxbaxaabbbaaaddacabbaacadbbaacabdbaaaaaacdaacbdabbacddbabaaacaadadxabxaabbxaxxxxadxbdabadaaxadxbxaaaaabddbdaaacccaacbaabacbaadbxaacbbbadbbccadabdabdbaabaaaxdxdbccbxdaxxaxbxbaxbxaadxcabcdxaxxdxdabadacdbacbababcadbdbdbxxbxxxaxdbdddadabdbabaaaadabbxcdbxaxbxxbxcdxabxcxacxacaadbaaadadabaabaadbxxcxaaxaxcaxaxbaacxxxbaxbacxdxxaxaaaxxababxxcacdxxxadaaxbabaxabdaxxxadbbaddadbabaaaabdbbbadabacdbaaxbxcxbxbxxaabbxxxdxdacxddbddbacdaccaacaaxcxbdbadacdbbacadabdbbdxaxdxxdxdxxbxdaxxbxbacbaabdbdbcdabbaadabbacadxaxxdxcxaxxacaxadxxxaacabaaaabaddaadbacbdadabacacbbxxxbxxbxbabxaxbxcaxbadxdxbdxxxxaaxbxaaxxbacabdaacaaaaaabcaaaaxbxbdaxdaxbbbdxxxaabacabbcbdadaaaaaadbdxbaaxxddaadaabadbdbadaabadbadabacdacxbxxdxxxcbxxadabbadadacacaadacbabaaadaaabacdbbdxxxxbaaaxdxxxxbaacxdbababdacbaaaaaaacabdbaaabddbcxaaacbbdaaabdaaaaabaaabdacacbdddacaaccabdbaacdacbbddbcadabbccaaabbaadaaaadbdbaaaaadbbaabaacadbadacabcbbbbaacdbaaxaxxxxxaxxbxbdbxbcdxxxxxdaabxbxxxbbccbdadaabaaacbaaababaaaabdbdbbaaabcbdbadxdxcxabbxdabxcxdxxacaacaabaabdaaacdbaadbaacdacdadabdxbaxaaxabxcdaacxaxacxxaaaxxxxxcaabxaxcxbxxbaxxacbbdbdacbaababadacadadbaxxxbxbxxcxbdxdbxcxdbbdabaccbacdbadbabdabaaaaabaaaacxxcxxaxbacdbcabbdadabbddadaaadaxxxxbxcbdaxcbbxdaxaaxdadaaadbxxaxxacdaxbxxcbdxxxbaaxdxxxadxacxadaxxbxabaxxxbcxxcdadxxabxxxacbdxbxaaxdbxxxbaaxxaxaadxdbbaxxxxbdaxaaabxdbxcaxxbxadxadaaadbbabdaadabaaacabxxbbbxxbxcxxxacabdbcdadbdaaadbdacbbaccaaadxaxxaxcadbbaaxxxcacbcadadbdbcbabaabbadabbddxxdabaxbaaxcxdbxabxaxaaaxxcbxaaxcxxcaadaxxxxbbxxxaabdacdadbaaaacbacdadbbaxxxxbacadddbdabacbbabacabxxcadadacdbdbacbcdadbbababbddaabddacxcaaxxxaaaaxxaxxaxxxcacxdadxaxbxadaaxaxxxacxxadaxbacdadabbdbbcccaacadbabdbbadbbcaacdbbaabacxxbxaxxdaxdaxcbbdbbcbbdabbdbcaaabdacdxxaxxxcxbdxbbxxabaxdxcxbxdxbxxdxxaxxxxbbabcdacaaaadbacacdacbabaxddaaabcbabdbadaaacaacdbaabacbacaaaacaabaacbadbaaxaxbxxbaxacaxdxdxxxxadaadaddbabdbbdbcadbadacdbacbcadbabacbdaaaacacbdacxdxbacxbbdaadbaaabaaacbabdbddaaccxdxaabxxbaaxxxabxxadabaaxaacxbxbxaxxxdddacdabacdbabaadbaccbbcaabaacacaccbxcbxxaxbxdbaxbdxbxxxabxxxcxxcxacdadbxdxacacxcaaaxabaxdxbxadbcbdbacbbdbababdbbaacbaxaxxbdaxaxdaxadadaaaaadbbbdacbadaacaaaxaxacbaacbdxdxxxbbbbbdaxbaccbdbabaddacddbacbadbddaaxxxdadbdbaxxxxaxxdadbxabxcxxaabxdxxaxdbdacbababcdbbaacaaacbdaaacbbdbcdbaaaccbdaaabdbaabdbaaacabddbabadbxxxdaaxcacbbbacaaacabdbbbbdbccdbacdaadbcbcbabcbdaabbdbabxxxaxcdaaadbccbaaabaabadbdbbdaaadbaaacaaxbaxxdbdbdxaaaxxxaabcxbxxcdbadabbaacbadbaaacbaaaaaaacdbcbcdbbabbdxxxaaxcdbaacdbbadaaaadbadadadabaaabcdbacbdxdbaaaccddaadbabdbbbbddbbaacabbdaacbdaaaacaacbdabdxxdxxaaxaacdxbacaxxxaaxxbxaxaaxxadaxbaxxbxdbbabbcbbacbaadadaadbacbdadaacbaddaadacabbbdacbacdaxxdaxxdxddadabaadadabaaaadbddaaaacbadacbdaxbadxbdxxxxbabxaaxbxxbbdbdbbaaaabacabdaaabbbabcdacdxxcbbdxxaxxxabaxxxxxxbaabxcdxaacxxabcbdxaxacbdacddbdabbababdaaadabdbacaaaaxaxbxadxdxxaaacdbxcxxacdxbdaabbabddbcaaaaacdbaacbdbcbacbaaaabdaxacaxxxaxadbdbbaaxxcbadbddaxaccaxadxcdxbxbxbaaadddabdxbxbxbadaacxxcbacabacdbdbdbdabdbcdbadaacaacdaaaaaadadbadacaccbadabcdabbbcadaacdbbdabbabbdacadabdbcaaxcbxxdabxxaccacdbbacadbdabaaaacbxbcxaxcbbaxacxxxxaxxxdxxbabbxcbaxxxxdbdaaabdbdbaddacababddbdadaaaabbadbdacdabbbababbbaxxxxxxxbbcxxxacxdxxdxxaxxaaxxxbaabxxacdbxxbcbxddbacxaacdacbaaacabbabcbaxbxbaabxdaxxxxxxxxbxcdxdbbaxcdaxdbadaxbxxxbaaaxxxaaaxbaxxxdbbxaxcdxxbbdaxaxxaabxdxxxadaxacbaxxabxxaaaaxaxbxxxxdxxaxacaaxdxxaxaxbdxxbdxxxbaxxxxxdxxcacdddbadadaadacadbdbdbdxxxacaabbdbdbadabbabaadbdacbdaabcxcdbbdabxaxxxcxxxxbxxbdxccdbababbdababdacbadbbdacaadaadaacdabaabdbdxdbxxxxdxxbdxdxbxxdbxdaaaaxdxbxbdbxcdxxaabxabbaxaaaxacdbbbaxaaxbxacaadbbaaaadabbbdacbacxbxbcxxaxbdbdabdbbddacbbddbdbabbdabadacbabacaxdxxbaxbaxcaadacxxxcddaxaxaaacbcabaxxdbdxadbacxadaxbcbabaaxxacxadabxbaxxdxxbdbxxacxdbaxacaxxbxaaxxdxadadabadxxaxbxaxbdadxxacbxdxxxdbcacaaaaaacbaabdbdxbcaxcxaadacbxcxdbabbadaaaaaaabaababdaadbbcbdabxadxbbacdaaxacxbbaadaabaadaaccdbbadbadbddaacdaadaxbdbbbxcxxdaaadaadaacdbaaacdbdacdabbdbaaccdbcabaaccdbddbbcaabbaadaaaadbabcdbdabacdbbacdbdxaacxaxcaxdbxxxdbbaabdadaababababdadbaxbdbabxdxaxaaxxxacaxbxxdxxdxabdxxadbcbcaxcxxcdaadaadaadbbdacacacaxxbcbacxbaxadaddbdaxcbxabaaxaxaxxadxaaxdxdabxaaxaxaxcdbaaaadaadbabdbdacbaaadaaaaccaxabadxxbaxaaaxdxdadaaaaacabbdaaaddaaadbdbcbcaaaaabdxcaaxcxbdxaadabaaadaaadabbbadadacaabdbddabdbacdaabaccdabaaababbaaacaaaacaaadbbabcadbdaaaabbbdbbabbcdxxdacccbadacabaacbddabaaabaacaabdaddbxaxxxabdxxaxaxxdbxbbacbxbxbacxdabxxaaxxadxxccxbdbxaaxaaadxcxaxxxcbdxxxabxaxxxcxbbxacxxdxacdaaacabddacbbcbadaddbdacacdaacxaacabacbdadaadbbdbaabbcdxxxxxbxabaabdaadbdaaabdaabaababaacabdbbadbdaacdbcdaabddadaacaaaaacabcbbbaaaaaaccbaadabbcbddaxbxxaacxxcxxbaxbxcbbabcbdbddbbdbaaaaacdaxdxxdxaacxcxbddaaadacaacacbaddaadbbdaaacdaadacdbdbaacbddabcdbacbbbdaaaaadacdacbbdbbcabbaaaaaadbcbxaxbbxaxcbadabaadbbaccccaacbbadbddaxdbbaacxxbaadbcbcacdabaaaadaaabdbaaabcaxadbdbabdaacbdacdaaccdbbaaaaababacdadbddabbacbaxbacddxdbaabbbadbdbdaccadaaaaaacdddxdbxbxcxdbxxbbdxxdxbbxbxabxcaacbbdaabcaaaabbabaaaaaaccbdababaaaaacddxccabbaxccbxbdxxbbxddaxdbxaddadbxdadxxacbcaabxadxxabbacbxxxcdxxxaddbdadaacdabadbdadabacadaabaacdaaacdbbabadaaaaxadxxaaaabdaccdacdbadabbacdbaabacaacbaaaadabdaaabaaxbdxbdxbxxcxxxaaxaxbadaadbdbaaadbaabacbdbbbacabaabaaadbaaabdbdbcbdaaaxxxxaaxaaaxxddxbxbxxxaxbxxxdaxcxdaxdbaaaxxxxxbbxabdaaaacaaabaaadadabdadbdaaadbbbadbadaaxadbxxxcxcxaxbxxaxaaxbaababacbaadacdaaabdacdabdbbdbdacddadacacdadabadaddaaaacdbaacbcbaaxxdaxdaccadbacbxxaaxabcxacxxbbbdxcacdbdadacbadbaacadacaaccddaaaabbdaaadbaadbxxaxaxxcbdxcbdxxcxbdxxaababbabdadbacadaadabdbddabadbdaaadbacbacdbxaxxabaxbbdaxbxdaxxadacbacbdbacbacbdaabdacabaxxbbxaxaxdbxxxadadxaxxxbaaabxbdxcdbacadacaabddbaadbbdaacxbxacaxbacdbbaaacacaaaaabbdaxxdxdxdaxxbxxbxcaabdbxdbabbbxdbxxbbdxxaxxbcaxcxxxddaaabxdaxxabcbbbbbacbbadaacdbdbdbxbdxcdbdabacdaacaadacadaadbdaacdxxdadxbxxacxxaadacccbdadaabdaaabaabaaaaaaxxcbdabacbabaacaaccdbdbcdbdaaaaaaccaaacbaadbbacddbdxabacdaxxacxxxxxdbxaadaxxabbbxaxdbbdbdbdbdadbbaaaaccdbcacaaabxaaxxxxaacaabaxbbaaxcxadbdxbxxxxdxcbxacxdbaxbdaabxaxbbacbbaadbdbaaaaaaadadxxxbxdbdbcdxdxxxadbadababdadabaababbbaadbaadbdaabaccdaaacbcddbadabcaaaxxxdbacbdaaxadaxxxxdadxaxbxbcdaxdbaxbabbbdxaaxxaxcxxxddxdxbxxxaxaxxcbxbbadababaaacbdbaaadaacdaabxxaacbaaaxcdadxxxcxxxdabdaabxxaacxxabxbdbxxbxabababbdacccdaacdbaabacdbbdaaxxdbabaxbacxxbabdbacaxbxcbacabdbadacacaaacxbdaacdacaaaacacacaadabdadaabbaddaacbxxdxaxxaaxabdxdbdabaxxaxaxaabbdxcaaabaxxbaxbaxbxabxxxxccaxcaxacabdbaaxxxxaaaxdaaabbdadbadaaaababbdaabbdbccbacbcdbbbdabdaabaaccbxaacabdbcddaabaddbacdadacbdbxabaxxbxaxbbaxdxxxaxbaaxxdxabaxadaxbabadbacbdacaaacbaabdaadbaaddaabbaadaabddbdddbdbbacxaxcxbxxacaxcbxaaaxadbdbdaxxxbbcbacbxbxadxxaxabxaxbxxadxdbaacbaxxdacaxaxbbdaxbdaxxaxdxcaadxaabxcacxxbxxbaacxxbbxbabxaxaxaaabaabxbxdabdbbxaxxxcxaxxxabcxdbbxxxxxxdaadbcbaaadacdacddaacbbaaaabaaaaadbdadaaaaacdbadaacbddabacxxbxxxaxbaxxbbdbxbbabdaabaaaacbdadbaxxxxdbxcdabxaxdaaxbxxxbaxbxbaxaaxacxabdadxxccbxxcxaccdaxxxaxaxxdxxxaxaaaadddabbbdaaaaacdbacaaadabcdaaaaaadaaxxxabxxxbdxxxxxxbccaddaabdaabbdabdbdacaacaxxcbxbxbcdadbbbdbbadbbdbddaaaaaddbaaaaacdbbbbaadbabdbbaadabdaaabcdabadbdaaaabacdaacxaaxaxcxxxaaxadbaxaxabxxxdacddacbabdaabbdbxdxaxxdbdadbxabdaaabdxbacaxxdxxbadbcbxxdxxxccxxbcabdadaaacabacbacadabadbadaadacbdbbbacdaaxacxbbadbdacaaaccbadbaaxxbbdxxaabdadaabaacbdaabdaaaaccbaaxbcxbaxdxaxdxaxdbdddacdbdabcbdbadbaadbdadabaaaxbdbaacdbdbcdaabbaccaddacacbxbxdbxbacxxxcbaxaxaadaddbadabacbabcbdbadacdbaacaabaadbxaaxbaxdacaaaxaxxxdxxdaxbaaxaaaaaaabbcbdadaaaadadadaaadaacddbacbdbdacdbadaddaaadaaaaadaaxbcaacadabdbabcacbadadbdabdbacxaaabdaxxbaaacxbaacbbaaaabaacdabdbbadxaxcxxadxxdbcxaddbaaabbdacbbacdbabbabaacacdbbbaaxbaaaacdabdaaaaadaacbbdadbdabxaxxxcdaacbdaadadbdbcaadbabdadbabdaaacbaabdacadxdaxxaxcxxcacdacbddbacdbdacbbaaaccdbdaxxaxadbaxxxxxxdacdxbccabbdadacdbdbcbbaacddadacbcxcxbxaacxdxxxaxcddbxdxdxxcdadaxxaddxxdbaaxcdaxaddadbaadbabbccbabbbdaacdddadacdbdbdbbdadaaadbdbcbdbbacdaxdxaxacdaaxddbcxadddbacdaabdbbbcaaaacbaddabaacdbdadacaadaadacaacdbabaadbbbbbcdadbaccdbxdxdxxbdaaaaaaacdbaaaaacabbadxxdxaxxabaacdbbdbdbacaaaabaaadacdbdbacbdaxxxacxxxxxdbbdxacdaaaaabbdaxbbxxbxadxxbxxaxaaaaaxcaaaaabaacdabbdacdabadadxaxaacadacbcdbbdaaaabbdbcabdacdbaabacdbdaaabccdacadaaddadacbbxaxxxadbbbbdabcabdadbbabadbdaccdaxxxxdbcbxcbaxxbxadbcxdaxadxaaxxaaxxaxxdaxbaacdxbaaaabaaabbaabbaadaacdaaacaaaaxxxbcbddxaabbadbacabdadacdaadddaabcaaababcdabadbdxcxbacxaaaxbbccdxdxxbbdaaxbaxbadbxccbdxxxadxaxxaaaabdxxxadbbdadacacdbdbabadaabddaaxxadadbaadddbdaacaabxcxxbabaxcxxxaadbbaaaxbxbxbxaabaxxdbaacxxbdaxbacbadabacabdbbcbddbdbaaacacddbbbbaaadbdbdbaadabaddaxabdacxaadaxaxdaaxxxabbacabxacxxxadbdaaadadbxbxbxaxaaxxaxabcxaxxaxxdaadxxbxxdacxdxxccdxaaxxxbaaaxaaaadbxxdaaaacbbbaabaacbbdacdbdbacdadbdbcbbacabaaaabadaacdbaaaacabdabbaaabaaabadacbdadaaaaabaabdaxxaxxbacdxxdaxabbbdxaadbxdxbaxadaxxbbaxxbbxxbxxxcxddadxabaaxaxdbacbxaxxbacacbxxaxxdbxbcaxabacdaaaacabbcdaaacacbbdaaacdbdbadaabaaaaxxddacxxdxadaxdaaacaabadaaaaabadbdbabacbaxxxcxbdxabaaaacbacacdabaadacbbadaaacdbbbcacdaabdbaadxxdxcxabaxxxcadaxdbacbbdbbbabbdbacaadadadbacdaaxxxxaaccdacbaxbxabcxacaaxdxabxbdbdbdddbaadxxdxxxbxbdaadacxbaaxbxabdbbaacadaaaadaddabxdxcbdxdaacbxxdbxcabcdbdaadabbbaccaadacacbdaxaaxaaxcdxbbxadadbxxcdbabdaadaaaadaaaabdadaaadaaaaaacaacadbcdaabdbaaababbdxbxxxacbbdbaxxxxdabbcbxaabxaxddxabbxbaxabxxdxxbdbbaxacdaxaccxxxadxxddxdxacddaacaacadbcdacdaadaabaaabcbxcbbdxxacbxxxxbxdaxcadxxxxcbxabaadbccaadbacbdabdadbbbaabbbdadbdbxxxbxxxbbxaxcxxdxxbxxbcaaxbdxxaxxbcxxbcxcaacaacccdacaaaabbaacbdbcbxxddaxaxxxaxdxbdxcababdxcxxcdxbxcaaaxdxbaadaaacbaabdbbaabacbdbacdaacaaabdaacxdxbbxccbxcaadaddadbcbadaaaaccxbxdxabxbaxaxxxxacbbabbbdbadabaaacaaaadbaaxbdxxdaxdadxcxaxbdxaxbdbxbdxbxxabbdxxdacxaxxaxxaaadbaaccddaadbdbaddbbdddaadababdxxcbxccdadxxxbdxxadaxbaaaabdadaaddbadadddaaddaabadababddbbcabaacbbadaadaaccaadbbbdbddbabdacaadaabbdbcbddaxxbadaadabcxaxbxxaxbdaxaxxxcbacdaxacbxbxbxbxxaxaxbdxxaaxbaxxxbaabbaababacbacdddabdbdbcacdxxaaxxaaxcxacxxdaaaaxacdacdabxcaxxaaabxxaxddxxxxxabxbdaxxbaxdaxxbaxcbbbdaxxbdxxadacxxacbbdbdxadxbdbaaabcbbdbxabxdbaxxxcbdbbdacabadbadadbdbdadaaxdabxdbxxxadxbxbabcdaadaddbaadaccacbbacbacbcdadbaadaaaadabadbabbdadaaadbdaabbcbcaacdadadadbaacaabdbbcaadacaacbdaacbdxdbxdbdadbdbdbxaxxdxdxdaabaxbxxaxdbxxxcbdxbcdxxabcxaxxxabxxbxaxaaxdxxaxxbacbaabaacxdabxdbdbabbdbdabbaaaacadaaadacbbbabbbabaadadacacbacaaaadaaccacadbdaaxaaxxxaxbxxdadxbaxdaabbbdaadbdxxbabdbdbdbdbaadbaddacxcxbacbdadabbabbbabaabdxaxbaxxcxxcxbdbbbxxcdaxacabbaaxbbaxbdabdbacbdbcdbbaacbaaaaacabbcabxcaaaabdadbdbacbacabddbabcaacbxdacaxxxxcabbaaabdbdaabadbdabcccbacadbbcdbxbcadbxxaacdbdxcdbdbacacacacaaadaxdbdbdadaadbdacaaacaadbacbadbdxxcxaaacaxcxaaaadxadadbabdabdaabbadbdadaacaxbdxacbbdbaaaadaaadbabacdbcxaxbdddbcdbdacaababdaabbaaaabxaaxadabdxabxdxcacdxxbaddbabaaacabdacbbcbdabacacaadadacbbaacadaacdabcaaabbabbddaabdaadaabaaxdaxaxxdbbxaabxxdxxxxdababdaxbdxcxxbxaxxbbxaacdaxxbbxbdbdxxbcxaaadadxxxaaadxaaxaaaxxdxxbdbaccacadaaaadbdaddbdacbdaaacabdbcadaabacdbdaaaabcdabdxdbcabxcaaaxxdaxaxbxxaaabxaxxcbacbdadabaddabddacdaxabaaacxbadaaacaacbdbcabaadbabaaccadbadaadbadaaaxaaabbdaaacaaacbaaaacxbdbdxbcbdxbacdbcdbaddbaaaaabbadbabdacaadabxaxxaxxaxdxxdxcdaxdxabadxaxaaaaacadbbacbadbbdbbacdacbabdbdbaacaaacaadbabbaaadbbddacabxdbcacadxbadxcdadbaababacdaaadacdacaadbdabbddbabxxdxabxabdabbcxacxbabxbxdacbbabbdacdadbdbaababxxdbcxxaxxaxxaaaacbbdaabacbbaacdaaddaddbdbdaadabaadaadabdaaacdadaabxxacacaabbaccbdbdbcbdaadxdaabaaacbdabcdacdbaacbaaaadaaaxaacdbxadbaddbxdxdaxbxxdaxbbxaaxdadbadbxaxxbaaadbabaabcdadaaacbdadbadaaadbaccdbaxaacbbaxaxdbdbaxxacxbxxaxbaxxxadacbdbxaxcbdbdxccbcxabbbbcbdadbabxbxbabadaddbacdbbdadaaadaacaaaabdbdbabcbcxaaxbdaxbdaxabdabxxxaxaxaxdaxbdaxbaxbxxcbaaxaadbxxbxdbaddbaabaadbbaacdadaaxxxbxbdacdbbbxdxxbacxxbxaadadbbaccabdbaaaaadadxxxxcxaxdadxxdadaxbxacbbaxaaaxbxaxadxdaxdxcxbdxxxaaxxdacacacaadabcadbbddacbccbadbddbaacaaadaadacabaabdbxaadaadabbaaccabdabbcacadbabaadbxbxxaxdaxaddxbbddaxbdbacbbbcbcaacdaaaaaddbdbdadddacdbdaaabacdxxxxdbaaadbacbcdbacadbaabddaabdabxxaxabbaabbxxxxbaxxaxxadaaaxadxdbxbxaxxacxaadadbxcbaxxxbbbacdaaabbbdbabdbdaxdbacdbabaxxdaxcbaxbabxxaaxbxdbacbdaadabbaacaaaadabaadbadaxxaxcbxaaacadbbacababdbacaaaacbddbabbacdxxaaxaxcxxdxxbbbdaaadaadbbbdadbacabacaabxxxxxxcxcxdbxbdbaaaaaadbdbaaadaacdbdbbxcccbdaadbaaaaaxaxxaxadbaxaddaxcbxdxxxxxcbadxdbdxcxdxxbxaxbxcdbxabxabdxxxxbdxxadbabxxxbxcdxbaxxxbdbxaxxbaxxbxdxadxdxbxxacbdxbdabxdbxbxxxaxadbxxabbabxxdabdbbxccxxdadacxabacxcxxaxxadaxcxxbdbxxdadaccxaaxaacxcbdbdbacbdbdacbacaaaacdbdadbxxaxxxxaxacaaabadaacaacbabdbdbbxcdxaaxbxaxaxxacaaxadbbdbaaccadbaaadbaccbadaaxxxxaxbbcaxxcabdbdaaacdbxcbxaxdxxxxxdxcaxbxbbdbaaadaadbcddxxxcdbdbacddddbacaddbcaaaaabaaaaxxxbbxddbbadxbxxxaacbbxxdaxxaaaxbaxxadaabdabbdbdabdbbdbdxaxxadxxxbxcabacdacacaabdadabaacbdxdbaxbcxaaxbxdxaxadxdaadaxxxdxdxdxxcbabdxxadxxbaabxbcbaxxcaxddbxxdxxxaxxdxxaxbxxaaaxxbxdbaxbdxbbcdacdbaaxxbxaxaxbxcbdxxxaxabcdddaaddaaacdadaaddbdbabaaaaaxabxxcaxxbxxaabbabdabababdadaabdbacdbcddaaddabdaaadbbdbaabbcdbdabdbdbdabddaadbaaaaabxcxxaxdadbdadbbaadadaaaabaaccxaadaabxdxxabdadbxaadbdacxxabdxddaacdaxaxabaaaxadxxbcabaaadddbaadxdacxaxxdxbaaxxxxdxbdbxbxbxaxxabxdaaxdxbxaaxaxxaabaacbbdbbbabdacdacdabbbaaabdaccdaadbddddaabddbxbacbxxxdxabxadbaaaaaaabaddbaaaxdadaabdbxxbxabxaxxbdadbcxxcxdbdxxxaxaaaxaxxacaaabadacbabbdaacbdababaaxdxxbaaxbadaxbxbaxxxxxbxdxxbdxabdxxaxacaccbaaacbacbbaaccaabxxxxadbcabaabdaaabaadaaxxcxdxaxdbaxabxxxdxbxaaaabxbaxxcaxbaxxdbxxcxxdxxbbbxdaxxbdacxdxcacxxddxaxbbacabxaxadacadacabaccbdacaaadbadaaadxxabxcxaabdbxxabxaxxabxaxxxxaxbxxbcdaacdbdaaabaadbbbbabaaxabacbxdbcdbacxaxaxadxacaxdbbdaaadabddbcaaabacxbbaxxxxaaxaxabacadbcdxcaaadbacaacdbaabdadabbdxcxbdbxdxadaxxbxaacxxbbaxaabdbxbdaccbdadadbdbaaacdadaabdaabbaaaaxxaabaxxacaaxbaddxxbxxbdadxcacxxbbacabaxbxaacxxdacbaaxaacxxbxaxxdxaaxxxxxbbdacdaaaacbaddbdbbabxbxdxxaxaaaxaxxxbxbxbxacabdacbacbaddbaaacabbacbxcxaaddbdaaabdaaabdbaaadxdaxxdacxadxcbxbxbaaxcaxdxcdacdbbbaxxaaxdbadbacxacxdxxadbabdbaxxbbbcxxcxaaacdbacdadbdbcacdaabbbaabdbadbdadbaacabdbabxcxacbcdxcdxxxxdxaaxxcaxxacbacacaadadaacdaaaacbaacdacacbxbdxcbabacxxbbabxbxadxadxxbxxxxdaaadbcadaaadxccxxxacxaddaxxxbabacadbddaabacdabddabdbbdaacdxxbbbdxabxaabbcbcdbdadaaabaaacdbbaadadaabdaabbbaacabdabacabadxxxxxxcxxaaadxxxdxabdbdbdbbacbxabcxaxdxdxcbxxcxxadbxxaaaaaxxxaacxxbxbbdxbdbacdabbcdacbaadaacbdbdabcdbdbdbxbbdxxxxacbdbcabbbaadaaabdaadbaabbdxcaddbadbdaaacbdaacdadbdbddaababdbabadbaddbbadababcaaacbcaaacdbdadabbcdaaadaabaababddacbcaaacbaabddaaadabdbbaacadabbabbbddxxaadxxdxabxxcxbaxabaadaxxxaxbcxxxbxdxdadaxadbxbdabaxxcbxxdacdaabbbcdabdbadbdacdbaaaadabdbcbabdadbabaadbcxxabcbabadbbxxxabdxxbdbacadbaccbddbaacdadbaacdbdbcbadaaaaadaaadacdabcbbaaabdabacbabdaacdxxxbxbcdxcxaxxadaabdxdxaabbxaxcxcxdacbaaxxcxcabadbxxdaxbxbbaababaccdaacdbdadaabbdxbbaxadaxxacxaaacdabdacdaacdaadaxxaxxbabbdxxxbxaadabxxxcdaxbxadxbccxabcxcadxxxbaaabxaacbaaaaadadbabdbadadaaaddacbabxaacaxbaxdxxxaxaaaxbxbddbbbdaddbaabaabbadabbcbbdbadaacdaadbadabaaaacbbabdxcdxaaxxaxaadxbaxcbxxdadaadaaaadaacaaaccbdbadacdadacaacaaddxdabdbaaababaabaaccbxxabbadbaxxaaxaxxxdbaxxbxxbaaaaadxbdxcxaabdxaxaxxbdxxxdacbacbacacddacbdbxxxdaxbaacbbdaacbdbbdadaaacdacbaaaaaddadbcbddddbddxbdxbaaaxdxxbacxbxaabxdaaxabaaxxxcxxddxadxdxxxxaxbdxdxxaadxcacbaabcdabxxxxxxxxdbxabxxxaacdbcbbaabbaaaacbabcdaaaaacbabaabdadaaadbdaxdxxaxxxaadxcxxbabbdaxxxcxadxxxxdbxxxxbxacaadaadabddbcdbadaddadabaababbbaaddbacadxxbxaxcbadxaabaaabbcaccdadababaaacbbbaadbaaabaacbdabdbdabbdaadabbddaacbbaaccdaabdbaaaadbdaacabdacdbbdxcxdaaxabxcdbcxbcxxbbdbbxbxxdaxbaaxbxxbabxadbaxxcxabdbxbxxaxdxdxdxdbdabdacbdbbbcdaaaaabcaaababaaabbcdaddadaadbdadbbbddbdbabdaaabababacdbbbabbaaxbdxdaxbacaaabaaaadbacdbababadbbadadaccabaaacccbcaxbdxcdacdxcxxxbdaxacdadabaadaaabbabdbacdaadbdbxbxxxacbaacdbdaddabdbacdaacxxdxbaxaxadaaxxadbdxxbbabaadaaacadabdaabdbxaaxddxxbdxaadxccaaabdadababbdbdadaccacbdaxdbcbadxxaxcdadaxxxxbxxcaxcaxxacxaaxabxaxbadaxaxacaxdaaaaxbaxdxacadbbaxaaadxxaadbdaaabxxxxxaxaaxxbaxadddaddbcddaaaadaaaaacacaacaaacbaaccaacdacdbbaaaaxabddacbccdbbdacdabdacaacdabdadbbaadxxxxaxcaxbddbxbxaadaaxxcabccbaadadacbacbbbbbaabbdaaabdaxbdbbadaccddbabaabbadbabdabdbdadbdbbdbddbdaacbaaacabdaadaabbadabbadabaabbdbacaadbbcdadaaaadadaaacbadaadadadbdbcbcadbaxxxdxaxaabaaaxdaabaxxacbxaaaxxacabdbxaaxxxdbdxaaxxabbcbdabxbaxaabxbxxbcbddaaaababadadabxaadbxxxadxxxbxdadbbxxbaxxxbcxdxdbbbabaadbaaccdbadbdbxdxxacxxxaaxbxbbabaacadacdadacbbbadaccacdbadxxbabxcacaaaccaaaaadadbdxdxaaaaabdaaaaaaaadaaccbacaabbcacxxxxdbxacdabxadaacaxxaadaadxxxxbadacabbxbaxaaxdbaxxbxxbxxxaaxaxaaaadbxbxaxaxxaxaxcbacxxbacbbacbadbdxxxaxxxxxdbdaadaaadacdbaaaadadbaacadabbddacdbbaacbcccbdacdacdaaaxaxacaaxaxbabcbbaadbdaccbdbdacxdaaxcbxbxxxaabaaxcbaxxxadbabxababacbbcbabbcdaaaadababddabaabcbxxdbxxdxxabacdbbaaaaccdbdbdbxacacaxabxadadbabxaddbabdaadabdbbcdddbdbdbdaxbxcdxaaxdbdbdbccdaacdaaaaadabdabbdbdaadbabdabxxbdaadxadabcxbdbdxcxcxaaaaxddbxaxadxdxxxadxxxcaaabxxaacaaxbaxdbxxxdacbbdababdbaaababcbadaadbdbabdbbadbaadbadaabbbacdbbbdbccdadacbaaabaadbaacdbcbadbaacacbbbbdxxbdbxxabdxxaaaxadaxaxdxdaaxxxdxdxxcdbacdbaabaabaaadaacbacdbxdxbxcxbdbxaacbaaacxaaacxcdbaxxxaabxxbbxaabcbxcxxbaxxbxxdxxacxdbdbbcbabaaaaabaaaaddaaacacaaabdacbbcbabaadabbdbdbbdabbdacbdacddbbbcbbabaaaabbbacdddddbbccbaaadbdbaxaaacacacacabdbcadadbcbdbdbaaxxaxxaxaxaadbdaxdbbaxaaxxaxacdxxxbaxxbdaabbxxbadbbaacbabdadaacaacbadbxaccxbadaaxbxxxdadxxdxdbcbxdbcaadbdaaaacaaabcaaabdabacbcdbabdaaaadbaaacxbaxdbaaabadaadadbdbadbdaddbaaaacbabaaabacxxabxxxxddxdxbbbdbdaacddaabaabbaxxxxcacdacxaxxaxcabdbdabdabcbbacabxxxbxdabxxaxxacdbxaxcxadxxbdbxxaaxdacxxxxcxaxcbaabxdxxbcxaxbaaaaaaadbababbcacdadbbacddbadxxxxaaxaaaxcdbcxddbdbaadacadbddadbdabxdbxaxbbdabdxaaxcxxdxxbxxadxdaxaxaaacxbcdxaxxxacxacxxxdabxdbxdxxbaxbxdaadxxxxxdxadbbdaabaaaaaadbbdacbbacbdbxxcxabcacbdxxcxbxaaabxxbxxcxbxccbxaaxxadaxxacxaxbdaccaabdbdxaxdbbdxxbbbxdxxxaxxbbxxcxxdaxcxcaabdabbaabdabaddbacdxxxbcxcaaaxaxcxadxxcbaaaaadacaddaaxbaaxxbdxdxaadxbcbxxxxxxdbaaccxaaxxbaaxaadxabacxxxxxxxxxcbxcdaddbaacbdaacddacdbbacbdabadbaaaadadbaabadaaccdacaabdbbacbbaacdbddbadbcbcbabcdabaadbbdaccdaacbadadabdbbddbbdbdaadbdaadbadaaabdaaacbadbacbaaabdbdadbacdbabaaccaacaxxabdaaxxadxcbxxxxxxadxccdxabxxxxbxdbaaxdbaaacbacdbacadbadacabbxxbbxdxbbxdxcxxbcxbaacbbabddaadaaccbaacbdacxdddaxxcxabaxxxxbxxxxcaxbxcxxabaxdddabxababbbdbacbdbadacbdbddadbxaaacxbdxaxcbbxxxxxxaxdbdxcbxdxbxdadaxxxbaxxaadbaaaabaaaacaaaaadadacdabccadbacaabadaabdbaccdbxxaxaxadaxbdxdacdxxcdxabxxxxxxxcbbdxbxxxdxxadbacadaadbdababdaadbabaaadabbabdbaaxaxdaadxaaaxdxxxccxxdxbxxabxdbxacxdbxbaxxxaxbdxcxxxadaxadabxxxcadxbcxxxbbdxcbdaaxxdaabdxacxdxaxxbdaadxbdxaxcdbdxxcabaaxaabaxbdxbaababadxacadxdbdbdxadbdxdxxbxaxxxabacbabbacbcdbdbdbaaaaaxdaxbbbxxbddadxdaxacaddbdxxxaxxbcxacacbcxxaaxxxaabacacdbddadbdabcaccbddacacbabdbcbaaabbabdaxaxadaxxbbxxxbbxaadadxxxadxacxbxbaaaxxxcaabbabacabdaddaacacdbacabxxxaxxxabdaabacbaxbacbdbbaaabcabbbadabxxbaxxxxxbadadabaaaaadxxxaxabdbacbadaacbdaddbbaaddabaabadbbdaabdabcbbcaaadbdabdaacbbxxbxdbxxxxabcaaaadxdxxxbaxxxddbadbxaxdxxxxbxabdbddbaaadabddbdaadabdbadabdacdbaaaadbadaabbdaacabcbaacabaacbdabxxbabxaxxxcxcbadaadaaabaaacxaaxxadbcdxxxaxbbbxaxxxxxdbxxxacabbxbabcbaaabbabcbadaacaaadaadbdaadacdbcdbbbcbbadaaabacaxxbdxdxxxbabxcacxbxbbxxcbcdbadbdacbdaadbaccbdacbdbaacdbxxxxxbxdxxbaadbxcdxxcbbdbdxdbcdbdbabcadacbdabdaadadabcdacdadbbcdaacaaaacddxcxdadaxaxbaadbaabdaaccbabadbdbacaxxxbxxdxxcdxaaxbabbdbaadbbdbdbaadadacdxbxxabxadbddxdacxxxdbdadadbdbbbdbdbaaaacbabaxcxxxaacadaadaabdaaabbaaxaaxcxxxacxaaaacbbaaabadbbaaadabdaabbbabdaxxaxbdxxabbxxaxabbabdbbbdaabbddbbaacadbbbabdbaacdaabcdxababbxaxbdxaxacacaabdaaadbaacaaacddaabddaacdbdaabcbbabcbdabacadbdbaacdadaadacdaxaadaxxxbbbbcaacbadbdbdadbaadaaxdbxxaxxcdxxdbxxxbaadaxadbbaacbacacdbacbadaadaxacdbxdbcaaacbaaadabaacbxxaaxdxxdbxcxbcbxxcdbdacdabadbdadadabdaacaxaaaaxxxdbaxxaacxaxxxbxacadbaaaaxxdxbdxxcxaxxabaaadbxxxabaxcaxxaaaaaxabbaaaacaaacbbcbabbcaxaxxaaxxxbaaadbacabdbadbcbaabxxaaaaaadxxdacxxxcbdacbddbdaaacdbdaadabddbdaacbadaacbdaabdbaadbdbbdbcacadddbdadadabcddaacacxaxxaabbxaxxdaabdbddadbbadaaadacdaadbacdaaadadacabbdabacbxxbxxdaddbbdadbaabaaccbacabxxxxdxxbaxxadadaabxbcbaxxxxxxadxxxcxbxxxbdxdbacaacbaadbaaaadxxxxcdaaxaxaxxbdxaxxdabxcacxaacdaxxaaabdxbxbdacxcdbdbxxxxaacbadbabadadaabcadabadbcxxdbxaaxaacaacbdbacdbbaccabdadabaaadaaddaacdabaaxxxxadbbcaaaabdaccbacdbaaaadadbdbcbaxaaccbbbdaaabaadababaacdaacababcdbacdacdabcxxdaaaabdaxxdaxbbadxaxxbxdaxxxxxxdbcadbcadacdabdaacbdbbaxaxacbaxcaaxxbxcxxdxxxadxaxxaxxdaadbacxxcdadbdaabdbccbacabadbdbadabxxxaddxbbxxacdaxxbxxxcxxdxxabxxxaaxxxdbdaacdadaddaababadbdbcdacdbdacaaxbbxbaxxxxbbdabacaaabadabcbcacbbbaxddbbxxbdbbacbdbbdbdacaaacdxxxdaxaaxadxaxaadadxbcdbbbdbabacadaabccdabaabbdbadaababcbcabaacbbabbadaxadadaxbdadaxaddxxbaadbddxxaxbdbbdaxbxbdbdabdaaacacbabcdbaxcbdbxxdadacaxxxbabaxdaxbbxxxbcdbxaxdbdaacbxbdbacxccxbbdaabdaaaabcaaaxaxdxbbxxaaxxbxdxbxxdbcdxxbxxxbbaxcbxaxaaxxcbdxaxbabaccacbccacdbbccdbddbaxbdbxaaaxdabbxaxaxxaaacdbdaxxxbbxxbdxcbaacaddbacdaabaccbbadadbaacaabbaaccbcxxaxdbdxxdadaaxccbbbadbxbaaxaxbbbacdadbacdacdabcdaxbdbbxaaaxaaxxaaadaaxabcbdadbdabbdaabddacabacbdbbbxacxxabbxdaaaaadbxbxxxbaxxbxxxdxdbcaacdabaaaaabxdxacxcxdaxdacxaadxbbxxxxxdaxaacbxxaxdbxxaaxcbacddabacbaacbbaadaaadaaadaaacdadxxxxxcdbxaxaxadxabxaxdxdxbaxbdabaxcaaaaacaadacdacdaacbdaaadxxxxxcxacaabaaabcaabdbbbbdbadacaaaacbbbdbcdabadaaaadbdaccabdaaaxxxacdaxdaxdbxxxdbxdaxxdbbxxbaxxbaacdbacxxbcxaabdxaaxaacdxbxabxaxcaaxbdaaxadxxxaaaxxxabxxxabbdbaabbaaadbababaaaccadaaadadbbdacdbaaadbaacdabaddbcdbcbcxbxxxadbadaaccacdaaaaaabaaabadabcxaadaadacaabdaaacbaaxdxbxxabxdxacaacxbbadxcxaxacdxaadaxxbaxbdbadaadxbcxaaxxaaaabaadaabcxbadxdxbxxxaaaadaadaabdacacadbdacxaxbdxaxadxcxadbxabaaxbxbdaaaaacdaadacacaaaxxaxxaadaaadbdacbbdadbdadaaacaaaaccdbbaaxdxdaaxdxxxadbxaxaxaxxaxbdxxxxaxdbxxxdaacacbdbadacdbbcdbacaadacacdbaddadabccababacacbadabbaaddbacbababcaadaccacaadbcdaadxaxadbacadaddaaabbdabdaaaddabacxcdbxbaxbxbbxxxxxaadbdbcbaaxdbaaacadbdaadbcbcaaddbdbdacxdacxxbxbxcdxbxcxxadxccdaacbaxdddxxaxacxxaacbabcaadbacbbababbaaaabbaacdaabbbcbbdbxxaxadbxxxxxbaaxadxabadadacccdbbadbbbacbacacxxdxdxxbacacdbaabbaabacaaadadbaaxdaxbadbdaadbcdbaaaaaacadababbxadbddbdaadaacaaabaaacxabdbdbaabcbaababcabcdbdbbacbbbbadxdxxdxxaxaaxdaacbaaxdxxaxbxacxxbabxxaabxxbddbaxdbdxacbdxxxxbaaxaxcxxdaxdxxxaxxbbcxxaddbxxaacxdabdbbaacdbdaacbbbdacdaadxaaaadacbbbbbccbacdacbdadbacdbaadabacbbacdadbdacxbbxxxbaxaaxbaccaaababaadabacadbaaabaxxabdxabxxcdbxaxxxxxaxdxxaacdxxabxxbxcdxxxdacxdaaxaaxxxxaxcdacbdabacbacbbcababdbdaaabcbcddbabdabbbaaacxaaxxdbacxdxdbxbxxxbcadbdaaxaadbaacaxdadxxadaxbaaaxxabxxxxabxbbbxdaxdaabadbabadbcbdadbdbdaadaaaaaaxadadaaxaaacbabcbbbddacdacccdabaddbdabaacaadabadbbdxbbxxcxbdadxcacbbbaadaaaacaacbdbbaxxxbacdxdaxaadacabxdxxxaaabadababadbbadabaaabadbdaaacbdaacbaadaaaaaxxddxxxbdaaaxcdxxaaaxdxaaaaxxxxxdxxaxbcxbaadaddaaaaacadbbdadaaaaabdaaadddbabcxdaxxaxdaaaacdabdbdbaabbdbcbacacbbdxxdadacbdaaccbaacdbcbadacbabdaaaacadbdbcadbaddbbbddabacacdaacaaaaaaxcxxadacbadacacaabacbbaabadaxdaaabxxbadxxbxxxaxxdxxxxdxccbddaaxxdaxxxdaxaxccxaxxdaxxxbxxdbxxbddbbxddbbacacdbabacbdaabdaaabbdbbbadacdxxdbxabdaxxaxxdaxxcccxxaxxxcbxxbxxbcbxdxbxdbaxdaaxxdxxxcaaxabxbaacacbaaaaccdbdbdbadbdadabdaaaxaxdbddbxxdbadacaxxxxxdadxddbbabdaaaaadaacdacdbcdxacdbbacbcdaddacddaaababaabcbaadaadbaadxabaadaacaaaaaacxxabxadabcxxxaxxxxxxdxabdbaaacabaabcbdbaaadabaadababbbadacbbabdacbaacadaadbcdabaddbdabacbxaaxdacbdxdaaxcbxaxdxbdbxabbdbabddaadacdbacadbaacbbbaaxxaxadacxabbaxxxxxaaxbxaacaacbdbdbaabbbdbxxdbaabxabdbcdbabaaacdaacdxaccdadbdadaaaaaaccbdacdacaaxxdaxxdabxaddxxbdbcdaadacaabcdxaxdaaaadadbdabaddabadbbaaaacbbbxxxcxxaaabxxddxxcbxabxxxbacaaadbaacadabcdabadbbbdaaaaacaxacbadabaacbbbadabaaaadaacaaaxaxaaxadxbxxxdxxaxaxaacaabdabxxdxxxdaaxxdaadbaabbdaccccabababdaadxcaxcdbababadbdbcdaadabdaadbbaabbacabddaccabdaadaabdabdadadabadxxaxxbbxdxdxxaaxaaxxacbxacxdadbxbxaxadbcbxdxaxdxxxdadxaxaxxdaxaaaxaxabaaxxxxxxaddabacdaaadaaacdabadbaaacdabdaaabxxxcabbbacacbabdaacaabdaaaxxcbddxdxcabxxacdacdbaadadaacdaacadadxaxbxxcxbxxdaxxbdaxxxccaabaxadxxxcxbbxdbbadaxaaxcxcaaxxxaxbxadabxdabcaabaacaaacbcbbadbbxacdaaxaxxadbaadbacdbbbcdaadbaabadbbaabadbabcadxxdabxccxdadadaxdxccxxdxxxbaxbdaadxdddaaxadxbxcaxaxxbxacbadaabaadababaacxbdbxdxxbxxbaxaaaacbdxxxdbacdbxxdbdbdxcaaxxdxdxbaxbacadaacdacaxxdxxxxacdxxxbdbbbaaacaccbdbacdaxbxxddadaabxbxxbxadxaxxxxxbxabxxadxxdxbcbbaaxbdxdacxxddbcxxccxxxcdddaaaxcxxxcbxaadxdxbxxdbbaxaabaddbcddadbbddbaccabbaaadxccbaxxbdxxbxbaaacxaaacbxxcxdxxbaxabaxaaaxdbdxcbadxaxaccxbdxdaxdadbcdabaabaacdaaadaacbaccacxxxaaxcxaxxxaaxaxbxxxcadxdbbcbdaadbacaadbdabadabxbacddabdabdbbaadbbadadacxbxxxaacacbxdxxxdaaxaadaxxabddxaacxaxaacxdxdbxxbbaacbdxxdbxdbbxbdxaxxxcxxabxbaacxaxxaxxadbxxbaaacxxdxxxxaadbdbbcxbxbxbbacaabdaaaacdaadaadxacxxbccbaxaaxaaaxxdxxcdxxcaxxcxxaxxxbaxbdxaxxaxadxbdbaxdaacxabxbxaxbaxaaxxxababbdabacdbadbdacdbdaadacdbdaaadbdacbbbcacaddaccacaaaaxadabxxxxcxabbaadbbdacbadbaabbddadbbaacbdbababcbbaadadxxxxxacaxacxxcbcxbxaadxcdabxbxbbdxaacdxbabaxxaabxabdadadxaxbaxxaaxaaaxxbxxddbbdbdbxxbxxdxxaxbdxcacdbxbcxxcxxbbacxxxbacxbacaxxxbaxadbbabcxxxaddbdxdaxxxbdbxbxcabdaacbbddbdbabdbaxddabaaadacdacddbdaacdabadacbabacaaaadadaxxxbxxbadaxxaabcxxxbxbdbbaxxdbxdaxdaxbacdccdbdbaabcaaaaaabdaxxdaxxxbxxxdxadaccbabdxaxbxbddxbcbaxdadbbcacbaadbcdaacdbbdaaxxxadabdbdbacbaadbdbaadbcdaaadbxacxcxbbaacdxxbdxxxdadxcdaxaababdxxacxcaxbaxbxxxaccacxaaxxxxbxdabxaxadaabcdbacadaacaabdxabaxacabxbdxxaaxxadbabaabcdbcbbbdbdbbdadacababxxbaxaxaxxxxdaaabxxbbadxxaxaadadxxxdxcaacbdxbaaxdxxbaxxdabdbxxdxcbdxxxaacxcdadxbabbdbdbbbcbdadacdaxdxxxxdxcxxadbaaaacdbbdadbbadbbdbbxxxaaabcxacxbaaxxxaxaaxbdxbaaacaaaaaabbbabaxbxxbbacaxxbxxcxxaxbcabcadadbaacbaaaacbadbdaacacxxaxaxaxaadbaxddxxcacadxdacxxadxdxcxxdadbdacbaaabbabaddaadbabdaacbaaadaabdaacxxaaabaaxbxxxxxacaadaaxxdbddadbxbxdbaadadbdbdbdacdadacabaaadaaabadddbxaxxxxcbcaddadaadbabaaddaabacbbxdxxxdbaaxxabaxadxdaxxbbcdxxaxaxaxxbxdxcxxdbaxaaaaabaaaabdadadbbabbaxxbabaxaxxaaxxxbbxaxaxxbabxaxacdxdaxaxbcbaccxxxaxxxabxacbaadaabdaacadbabdbcadacdbacbbadadaaaaabadaaaxbxaaxxdxbcxdaaccxdxdbaacdbdadaabbabaadbdbcbadbxxbxaaxbxadaaacdacbdbbaaaaddabacdbaaaabxbabxbxcxabdaxdaxxaadbadaddbcbdaabbadddbcaabxdbdabcxaxxdacdbcddaadbdabbdbdxaxxxxdxxbcxxxdxcbadxxcxdbadxaddxxxxacxabaxaxbaxdxxxxbddacacdbdacbdbbddadadxxadadbaadadaacdbdaaacddabdaadabdbdabdaacdababbaxxxxxcbxaacxdadxdxxdxxdbbxdaabxacaabaxddaxadxxdbbxadxxaadbbaaacacbdacdbdaacdadacbaacbadaabdaddaacdaaaaaacadbaadaadddxadadadbdadabcbbabdbcdbaadadaaacbbadabbbcdaaabdadbbadabdaxacbxdadaxaxxcdabxdxaaxxbdxdxadbxxcbaxcbdxdxaaxxxbdbcbdxxaxbaxacabbaaabbddbabaaaadaacabxdxacxxacaxaaaaxbaxaabxcxxaxxxxabcxxababdaxbabaacacxxxaxxadaaaaxxxaxaxaxdxdxxaxacdxabaadaacbadaacbacdaababacdaacabcbddbaxdxxxxacxxxbdxcacxadxxaxdxxcxcbdxbxbdaacaaaabbaabadbdbacxxacxcaaxxxccxxbbxbxxabdxcdaxbdxbxcbbdbaaaaxadxdxadxaaxdbadaxxdxaacacdabbadaaccbdaadbabccdadadbdbacaddbaadbaaabaadabdacbbabaccaccadbbaacadaadacdbabaacdaaaacaaadabaaxxxadacadacbddacacbbdadaaacabadadddbaaadaabababbdxaaxxbcxdaadxbaabaccdbdabacaadbaabbdxadabaxaxxbxxdddabbadaxxxbxbxxxcbaabddxdabdabdbaaaaabdacdbaacdaaaaaadbaaadadbdddbaabddacbbdbdaadacdbadbdbdaadbbcdacdabcabbabaxbxaxxabxaccbxxaxxxbxxacxxxaacxdadaabdbaacadaaddbdaxaadadxddbxbbdxcbxbxcbxdaabdbacdaadbdaacacbaabxxdxaxbdaxxxbcxxacbbcaaxxxdbaxdaaxaxbdbbbaaxxdbxxxxbbdbdxxxbabxxxxabbxbdaadaabbadbdacbbaadbababdbxbabxxxdaadbdaxxcxcacbcdbddbbacbacbxdabdbbaaacaaaacbadbdbadacaaacbaabdaddacdabbbxdxxxaxcabdbxdxxabdaxbxxxcabdbaadbcbbddaacbdabacdbdbacdxxaddabdbbddbdacbdbabacacbddacbaabdaaadabadacdaabdaxaaxbaxcaaxbxxdabbxaaacaaacaaababbdabdabadadadabbbbabaaabdabadadbadaxcaxbaaaxxxcdbacdadbcbcdaaacadbdabdaaacaaaacdacdacaaddbaadbbaabaaddbdaadabbdaaaaaaaxdbxxaaxcxbbadxxxxxacxbxabxdxxxxacaaaabaacacccdbdaaxadbdacaabdaaccdaccacbaaadbaacbadaababaabaadaaccbcbdacxbxaxabdxbdadxxaxxaxacacbxxbxacaxxbadxxxbxdaadxadbxxxaxacxxbacxbcxcxaaxxbaxbbaxxaxcxbxxdxdaxxaacxadxaaxxdaxxdbaxacxbxabxxdbadaacxdxdxaxxdxxaabaabxaxbaxdabbxbaaaddbbaccaacddadaabdbbccdbadaaabdbdacbcadabccaxxcbaadxbdxbxbdacdxxxaadacxbxxxdbdadbbacadbdbdbdbbaaaxxdabxddadaxadbbxaxxaaxxccaddxxxabdabadadbdxxaxbabdbcabaxxaxcdbdaaaabdadaccaabaabbxxxcaaxxdacbaxaaxxdbaxbxbcxxxbxxxacaaaabdbacaacabbdbdaaabbdbcadbadbdadbbddadxdddaaxxcabxbxaxxxaxaxxaadxbxbxaxccbdadbaaxxbbxaxxxdxbaxbcxaxbxxxabxadaxaaacacbaddadaadbaaabadbcacdabacbadabdaabbbdaaaaaaaaacbaacccabdabbdbadbbdbadbbaadbdbcdbabcadadbcabxaxxxdaacxxadaaadadabbcbaabaabbaabacacaccxxxacdxxcdxxxdbdbaacacbadacbdadaccaadbdbaddbbacaxxdxbdabdbxxbxxbcxadacabxxdbdbaacbdaacbaaabdbdabacdababxcbdxdxxaaaacdbadxxbxxcxabdbbbbaacabbcacabacadbaxxxdxxcbbdxxbxbbxaxabbxaxxxbbxxbdxxdbdxaxbxbadxacxxabbaxbabbbxaaaaacxxxxaxbxxabdaaaacabbacadbcaddacbaxxdbxdaxaxxaabxabbxbdxdaxxbaxxbaxxaxdbcbdbbdbabaddbaadaaaacadbacdadbadxaxaaxaxaxcacxxacxxdxxxcxaaxabaxbdxxadbxaxdxxcxbcaxxxxaaxbxxbdbdbadabdaaadaacacdbaacddbbadabdbdaadbddbacadxxxxxbxddxaaaaadacbccdddacxxaabxaxxabdxbaddbccdbcbdabaadaacdaacadacbababaccaaacbbddbacbdxxxcbxxbxcaaxaxxcdxxxbabxcbdadbaadaadabdbdbaabdbbxbaaxdaxxaaxxbbxxabcdxxxbxxdbccbbcbdbdacbdbadbdaaxxbxcxcbbbaxaaxxdxxxxxxxabcxbaxdaacdbdadbbddadabaabcbdabdbcaaacdabcbabcdacdbxabdbxdxaxddaadbaaaadacaxxxbxxxdxxxcaabxxdxxxcxcxaaxbdxadbxdxaxaadadbadbdxdadaxxaxbxbacdxxxbaxcacdaadaadbbcadbdacbdaacbabaaddaadbbdaaaddaadadaaaacabaaaxbaxdbxxcxaxxaxcdxaxaabaaabbxxbaaxbxcadbdadbdbacabcbadbdbxxadxcdbacaccbbdxdaaxcxaxbxdxxcbddxaxcxcxxdaxbxaxxxxddbdxxabaaaxabdxadxaxxaxxbbadxdaxbcdxaaxxdacbbxxxxxdadaaabbxbbaxbaaaabdacxxaxxdbbaabdbdxaaaxxdabxbaaxaxaadaxxxxbdbdaxccbdadbacdbadbdbdacaxaadxbbaaaxcxxbxabdbdaabbacdbabadaxaxxdbacacacbxbdbdxbaxdbxaxdxxxaxxdaaxaxbacxxaxaaaxxcbxbxaaxaaxxxbbaxxaxxbxaxbdacadbaddaaaaaxaaxdaxxdbdabaabdbacdbddabbabbcbabdbbbaacaacacbcaxaxaxcbcbaacaacdaadadaabaadbxbxxbdxxaxxdaddadaabadadaaadbaxaxacaacbbaadaaadbdbdacbadbdbdbxxaxadbbxxaxaaaxaxxcxxxxbaxxdxbbbaaacbacdaaaaabdaabacbcdbacxxaaxdbxdbaxdaxaabdaxbxxbxdadaxbdxxxxaadxdbaxbdbdaaxabdaddacbacaacaadbdaaacbaaaxxbdbxacbxdxdxxacbadadxdaxcbcbbxcxxxxaadbbbdbdaaacbadbacaddbdabaabcbbabaxacdbdbaadabbdbabbabcabxbbdbadabbdaabcbbdbacaacabcxxaaacxbacbdadxbxddaxddxababdaaabbaaaaaadabaaadadbbdaadbadaaadddaacbabdaacaaadbaacdaaxaaxxxxbbdaacdbdabacaaadabbabacbdbbbbcddaxxbacxaadxbxaabcxadxaxxxcaabddbbaacdaadaacacbbcddaaaacdaxcbadabcddacdbcbacabcbbdbabbabcdaacbaaddbcdadbaadabbbacaacaabaxxxxxdaxxxcdbxxcxxcxxaaxccaabaababaaxdadbcdbbcadaaacdabaadbbdacxxxaxaaxcxxaaxdaxcdxdxbacaadbaabxddxbaaxxdaxaadaaxcxxaxcbdxdaxxbxabxxcbdxaxdadaadbdaaaaaacadadbadaaaaacabadxaxaaxxadxabdaaxbbbxxcxxxbaxcdaxcxbxaaacbxbbxabcxxaxxxxbxxbaxabbbddaxxabdbxbbxaxacbbacxcxxacaaabaabdbbabcacaxdddbadxacbxbccbabdbcabdaadacacdaabaaxxxdxaxcxxxaxaxacbbabbbdbdbadacaaadaxbbxxxdbxbxdxxbdbadaxbacaacbcddbccbbaaadabaaaacaaacbdbdacxdaxxxacbxxababbxbaaxcxcxbxdxxdxxabcxxdbdxxcdxbdaaacdbxaxbxbbdxcxabxxxbdxxxaxaaabaaddxdbbaaxdbbcxxbbdaacbdaacaaacdbbacdbacadbbbacaxxxxdaadacaadbbaadbcaaabaabbaxbxdxaadacdaxbxaxbxaxaxxdxdxaddaabxxaxdaxbxxxxdxdaaxaadxbdadbxxxaxxxacxaccxdxxxxaaxaxxxxxabaabcbdaddbbbdadbadbabadadbcxbxaxbxxdxaadaadxxaxaxadxxdacdbadbadbadabcabbdbdacbaxxaxadacxxdxxxxbxxcaacaxbacbdabdaccadaabdbcdxxxxbcdacaaacaaaacaaaacbaadbdabbadaaaabbaccacbacbdbdadbxxxaxbabaaxxbbxcdxcxxxxxxxxacxxacxcxxddbbdxxbadbabdabaacdaaaaaaacdadacdbddbcacbaadaaaadaabacaacdbadbxaxxxxaxcaacxaadbdacadbaaaaabdbabaxaxdxcaadacddbddadbbbaddabaaadacbacacdbdbababcdbdaabbacccabdbdbcbcdadxadxxxdbxxxcdadbdaabxxaadbbadacaaaaacdbaacdadaaabdbacabdaadaaadabdadbbabbdbcdbaadabbbaadacdbbbdbaaadbdbdbaxdaxxbdaxbxaaaxaxxdxxxabaxaaababcdbdbdbdbabdbaaacabcdacdbadadadbadaabdbadbadxaxxbxdaxxxxbdacbbabbcdbbadaabacdadbacabdabcacabaaaaaacxbxxdxabdxaxcbdbxcdxxcaxdaxcadadxxaaxabaxdxadaxdxdxcbadxxxxbxxbbxcaxxxbbbadaaxabbaaddaabxaaadacdabbaaabaababacdbaabdbbbbadadbbbbabbadaabdddbadabdabadaaaxaaaabbdbacbbbabadxabbcaaabdaacdaabadaxacbdxdxcxbddaaadbxbxadaxbxcxaaaxbxadbxaaacdacdaabaacdaabbxbaxxxaaxcxaaxdbaabxaacacdacdaaxxadxxxxaaxdadaadacbacbaacadbaaabdbabdaxxdabdxddaxabxaaxacdaababdadabdbcaaxxacabacdabdaadbcdbbbddbdxaaxxxxxbxxxxddbaababbaaaaxdbaaxxddxcxxxadacbacabbadadadbbbababdbcdaacxxxxbaxxdxaadbcdbcdadaadacbxabaxabcxabddacacxxbxxdadabaaabdaabaabdaacacabadbbaadxdxxbxbxxxxxaxxbdbbxxaabcbccxaadbaababbbdbdaaacaabdacaaaabbbdaxdbxbcxaxdbxbaaaxacdbddbaaababadaaacadadacdxbxaadxdaxbacaaaadbaadbaacbabdbaacbcbababdxabaxxaaaxbabdbaaaaddaadbabdaaacbadaaaaadacacbdbaabbaxbcdxxxabaadacbbdacdacaaaccaaaabacxxadbxbxxdbxaaadxxaxabcbacaaacbdbbabccdbdaaxbdxcxacadxxxdbadadbxaxbxbbdxadxxaccxdxdacbbbaadaadaacdadbdacbaaaaadababdbabxaxxbaxbcxabxbbaaxbxdxbxabxxxxxaaddaadaaacdacaabdbdadaxaacabxcbxaaxdxacxddxxaadaxacbababcabaaccbbdbdbddaaxbaxbxbxxcxxxxbdxaxdadbcxdbaxxadaaadadbbxaxdbxaxaxaxaxxdxxbxacdxdadxbxdxxbadbdxcxadxaxdaabdabdbadaaadbbacdabadbcaaxacbadacbdxddbacxdbxxdaaxbxdbababadbabdbdbaadadbbdbdbdbaxaabxaaaaaxdxxbcxxaxaaxaxbaabdbxxbxbbxbaxdxacddbcaaacxxaaaaxcbaxxcadaadbacdbbdacbaacbxxcbaxxacbxxxxaaxxbxcbadxxbdxxabxaadxxxbxxxbccdaxbxxaxdxdbaxxxxcxxabadxdxbdaaaxxcdaxxbcdxxcxxxdaxaxxbxxaxcxxxbcacxxxaaaxxxxxxabxaaaabdadbadabccbbdabxadaxdaxdxdadaxdxaacxxxxbaxacaxaxxdaxxxxcxadxabbdaaaaxaacxxbbxdxxxdxcxaadxabbdxbaaaxadaaaxaaxxaxcxaddadxdxcdbacxdxaxcddabdaabdabacdbaccbabdaxcbxxdadabaccbaaabcaabcadadxbdbxaxxdbxbxaxacxabdaxxxbdbxbxbbacdbbdbadacdadaaaadbabbbbabdbxxadbaabbbbaacbdbcbdaccdbaacddbbaaadbcdaacbdbaaadaxbdxcaaxxaxaxcxaxaxacbdxxaaacbdaadbbaacbacdbdabbaaaaacabxbaxxaaaxaaaxababdaxxbxaxxxxddaxabxxxxbbxbdxdaxxxbbbaxaxbdxxdbxdxbdbaaaaxaxxxxdxxdxdaxxxbbdxdbxaaaxxxbbxxxbaxcxacdxxxabxacxabadabaadbaadbaadbbaaabbcaaabxxxxbbacxdbbadabadaaacdxbdxddbccbadacddabcdabbadbdbdbdaaacdbbadxxabxxbaacbacdbdadbaccbbbaabdaabdbddaaaadbadbaababdaacdbacacdbacdacbbacaxxxdbacdxaxdbdaaadbaxxxdxxbxxbcxxaaaxaaxcxbxdbdabdacbddbdabdbbccadaaxaxxxxacxaadbdbxxdbdxxdabaaxdbxxxxxxxxabdxbdbdbacbaaaaacdbabbdaaadbbbddbaaaabdbadacbcbbabbdbadadbcdacccaxxdaaxbcxxdbxxxabcxxbabbxadabcbxcxadaaxxaxdaxbaxbxabaxxdxcdxccdbxxxaxabxcxcxbxddbxxcaxbbxxdxxabdxaacxacxxxbaaxaxxadbxxxxxcxdxddxbaxxxcdxaaxcbadaxxaxaaaxcdbadxcxxabaxxbbbdaxxxxdxxxxaxacxacbcdababaxxaaaaxaxcbdaabxacaxdbcbaaadbbaddaadaaacadbadabdadadbabbaaxxxaxababaacacbadbadbbaabadbddxxaadxadbdddaadacdadaacccddxdxxxbbaxxbxaxxdbdbdxdbxdxbdbxdaxaxxaxxxbcxadadabxaxbcxxxxxaaxadxabcabaxxbadaxcxxcdxxxaaacxxbbdaacaabbbbaacdbabbdbcaaabdacdbcxaxxadaxaxcbxxacxxaaxaxxxxxbxbxadaaabaxxxdaxaddxxaacbaabdxbbxcxxdxxaxcxbxbbbabadbddaacacaabxbaadxacddxbaabcdbdxxbbbxxxxbxdadabdbdabaaabcdaacdxxxxbaxcaxdbxaxxbddaacaaabaadabbdadbbbcdbaadbabacbbdbadbaabbbaadacaxxaxcxxacbacxxbdadbbadacxdbbxxcxdbbaxbaacaxxaxxadbaxaacdbdacbcbdbacdbdbdbdaxbxbdbxaxxaxxxacacacaadbacadbabaacbaadacccdaadbaaaaacbadbaacdaaacbabacdaddacdaadbdaadxdxxaaabxaxaaaacaaccdaaaaabccxaabcbxcxacxbxabbbbaxccaxadaxcabxxbxbxcabaabadaaaaaaaadabdbddaxbxacxbdxaadbaaaabcaaadaabdabdbdacdxbxxacbdabdxxxddbaxabxxxaxxxbbbdxbcaaddbaadabdbacbcabbaaaaxxxcdadbbdbdbacaaababcadbaaacadbaadbdadaadbbcacaacxxxbxcaxadxaxxdadbcxccdbdbddbadbaabcadxaxaxaxadacadaaddxxabcadxxbbaabaaacbabaabbxbaabdaaabcdbaabcdbaabbadabbbbaacaabacbaabbcbbdbdxbxxxxcdadaaadaadabaxxxxxdadbddbaadacbaddabdadacbbbbacaaaadbbbaaacdaacbaccadadbdaccaxxabxaacdacdbbdabbdbaabbadbaabadaacddbdbddbxadxbddxxaaxxxaabddacdaaadbdbabcdbxxbxxdacbcxxaxbbacbbbxacbbxxxaxxaxdxxxxbddxadaddbbacxdxdxxdbxxxbxcaxacbadaaacdabdaddadaadbcaacbbdbbaaxxbddbdxdabbaadbdbaacaababcdbabaacbdbabacdbacbbaccddxcxdxdxbabxxxxbxdbaxdacxdbddxaaaddxaxxxaxabaxxbxxbadbcbaabbaabaacdadbdaxbaxcxxaxacxacaxxxxxxxxbxadbdxcxcadaaaxxdbaaxdabaadbadaabdabdaaacaadbdabbbdxaxaaxcdxdxdbbxbxbxxxxxbdabdbabbxxxbxaaxbdxacxbdxbxbxbaaxbbaxdadbdabdacbdbcbabbcaddbdacdaaddbxdbxaaabcdaaaxxcbaaaccdbbdadaaaaabcdbabdaccaxadabxcdaaxaxxbabxdbadadabaacdabacacddabxxxxdadbbaaaxbadbxaxaxxcdxcbxdaaxxaxxxxdbaxdacxbcdxxaxbaaxxadadbbxxbxxbxxdaxbcaxdabacxxbxdxxxbbxxaacxadxbaxddaacbbcdbacbcabbadbaaxbdxdbxcxdxxcaxaxadbaaxxacaaxxxxcdxcabxbcddaxxxxdaaxxaaabdabdbadbbcbcbdaaaaabdxcxdadxaxbaaxaadbadaacaaabaaaaxxaxcbdaaddbdaaacaaaabbcbdbxxaabaabxcacxxaacaaaadbcaacabxcxaxxaxaxxdxcbxbxxxxbbbdabaaaaacdbaabdaacaacaacaabaacbbaaddaccdbbaxbaxxbcxadacdaabbcdbcbbadbabcbbdacbabxaxdbaxxcbxxaxdadbdbbbaacaacabdabbxxaxaaxabxxadxabbxbbdaxxaabadacbabxxxxxxdbabddbacbbadaadbbdacbabbaaaaxbxbxxdxbxbabdbdaacaaaaddbcacddxxxbaxabxacbaxdxaxcxabbadaaadabdadbaccbdaxcaaddaxaxaxddaxxccdxdxaxaddxbdbadadbcbaadbddacbaacbdbaxxxxdbadaaacbdbdadbaaadbdbababdaaaxxbxadbxxdaaadbabbcaaadbcabdbdadbabxdxbdabaaadbbaababdabaadabacacxbxcdaxxxacdacdaccbbcbdacdacacbababbacbddaaacbaaacbdadaaxcxdxxcdxaxaxbxbacxbcxcxcxbdabcxdbxaxxaxxaadaaxxaaaaaabadbacaaaddabdaaadaabbbbdabcbdbabxaaxaxxaxxdxxaaaxxacxcbxdaaaxxxaxbabxxaaxaxaacxxadxxdbxxxbdbcxxbxxxbbdbxbacxbdbbdadbxcxbaxbxxxddbdbdbdbacbabdadbdabaabbacaaaddacaaadbdbacdddbbbaaacabcdadaaadxdadxdbbdbadacdaabddaadabaaxdxxaccbdxxxabxccbcxxxdbdbbdbcaabbcbaaccdbadbccdaaabbbdbaadacadacdbacdadbdaxaxxacbcxdxabxxxbacdaabdaacdabbdaaaccaaaadabdababbdaaaaaabcbxabcxxdxaxbxxbdacbaxxbabadbxdbdacbaacbbdaacbdbcaaddbaabxadaacbxxaxcabddbbaabdbbcdbddbadacbaadbdacbxxxbxxxxcaxxbdbbbdbdabdbabadbbaaaxcdbdaaacbaaadaaaxadxxaabaxbxxaxdxbxaaxxdaxxxxaxaabxdaxaaadaaaadadbbdabaaxadxabxdxcbxadbadbxaaxxxxcddbxxcxcxxcaxaabxbcxbabdabdbdbbdaaaaaadxxdbxxcdbcccdaddaaadacadaxxxxbbaabcxxxadxbxxadabddacbxxbxaadaadbxaaxcxbxbxadxadaxxaxxbdxxcxaxaaxcdxcxxxxbacbxacaxacaxaxbxaxbdbacdbcbbaaaabbaaacaadabdbdxbaxbdxaxxadxaaacbxxxaxdaxcxxaxdaxxabaabaxbacxbxbdabaaxxcxdaxxdbxaxabbbxxxaxcdxbaxcbcbxcdadxbdxxcxcadxdacaaabadabccaacbdaaaacdaxbaxxbxbxxbddaxaaxaacaadbbdbddbdaaccbbabdbdadabbabaaaadbadaacxaxcbxxxxaxxxdxbcxxbxxabadddbxcaxxxaxbxbxxabadabadaababbaaaaaaadbaacbabaxcaxadbaxaacaxdaxcdxccdaaxbxxbbddaaddxxaxdbbdbxxdbxaaaxaaxxdxxaxxxbdxbxxdbcaxxaxaadxcxcbdxdxdbaxaacbaaxxxbaxaaxacdbxbxbaxbxdbdaaaccdbdbdacdaaadbaadaaadaxxaadxxxxxaxdxxabdbdbxdxxxdaxxaxdbdbcxxdacxxbxdxabxdbdxbxdbaxaxaacccaacdabaaaacabaddaaaabdbdadbbdacdacaccbadbdaadaaaaacbababaacaacbdaaaabbccadabdabaacbxaaxdaccbaxxxcxxdbdbdxaaaxdxaaxdxaaxxdabcaxxxaabaxxxcxxacxbabaabdaxxxdxcbdaadaccxbxaxbxcabdxxcxacaxcxxbdabaaxxxaxbaxcxcbbdbxbabxxxdxaxbxxaxxcdaxxbxaaxbdaaxcdbadaaacbdaadbxbdabxbxdxbbxxdbaabdddbcxxaxbcxbaaaaxdxccxbdxdaabdxdxbxxbdxaacdaaxaaaaaaabcdbaadadaaabaabbababadadadbaaacddbddabbabadacbdbbcaaaccdbaaaabadbbbaxbxxxxxaxabdxxcxdbxaxxdxxacbxxxdxxaadadaaacaaadadaacbcabacbbaadadbddxabxaxxaxxbaabdbaaacdbdacbdaaabaaccbbaaxxacacxaxaabcbbadaxxbbxxaadbxbabdacbxaxaxabxcxbdxaxadaxaxxxaxdbadxcbxxxxcxxcbxxadadaaadaacdaabdaabaxbxxaxabcxxaaxdbabdbbcdadbcdaabcaacxaaxaxadxaacaxxaaddadbadbcbcdabbabacadbdbaacbabcbbxaxcxbdbxxabaxxaacddbacbdaaadabaacxdxdbxxxxcaaababccdacbadaabbbabcxxaxxxdaadxccbbdadbbbbadaaaaaaaccdbdbxxxcdxcbbxxbabxdadxcadbdbadxxxdadbxbxdadbaaabxbdxxdbxxdaxacxaxxbcbdxbxdxaxxddaxxccxxxbdxbbacaaadbbdbaaacdacbdaaadxxaacxcdbacbaxbxxbxadadaaxbxxbxaaxdacdaabadaacbbadbadadbaacaaacaadbadbaddbdadbabdxxaxdxaaaxxxxaxxadbabaxbxxxaacxddbacxxaxxdadddaaadbaacaabxxxbxaxbdaaaaxxbbdxaxbxaxcdaacxxcbxaacxdabxxacxaaxdbaaccbdbaxacxbdaxbxadaxdbxbdbaabaxxaxbxbxaxdxxbbxxxaxbdaabbadxxxcxxaaabxxacxxxaaxxdaabxxadxaxxbcacabdbcbababacdbabdbaaacaacabababbababdabxdxxxbxxbxxdxbxbcdxaadbbxdxdbxaxxxbaxdbcxdadbabaacbbaaaababadabbaabbaaaadabaacaadbdbdacadacaaaaaadacdaaaxacaaxxbadbadxxxbxbbbdaaabbacbbbbbabaccxbxaabcxbxaxbaxbaadbxxxdadaxadacbdaabadbaaadbbdxxbcxbdabxaaaaabbaxcbdxxaadxbxdbbxbxxbaabcabdbccdbcdadbdbacbadbaaacdaxxbxcbdbaxxcbxxbaxdaadxbaaxaxcxbxbxdxaacaxaxxdxxcbadaadbadbabdacdaaabbbdbbxdaaadxaxbxxcaaaxxbaxbxcbdadbabddaaaabbaacdadaaaaxxdxxxdabxxaaxdbxadadbcaaaacaacbbdabbccaabcddbaaaabdacbababadbbaadaaabxadbddadbdabacbbbbdadaxcaxbaxbabxbabbdbdacadbaaaacbabddaabcbadaaabaabaadabxaaxacxxxcxaxdadxxxbdacxaxcbxabcxaacxbacxxaxbdxbaddxdaxacxxdaaadbcbaacaccdbabdaadabaacbdacdbbdacbdaadaacdbdababddbbdbbacxbdaacbdacdabacdacbbdadbdaadbdacxxddbaaaxaadxxbbbaabbbbbacbdbadacbdbaabacaacbabdbdacbaaaabxaaxxxxxaxaxxcaxxcacdbaadaabbabbacddacadabdaadbxxdxbdacxxadxbxaaxacxaxaxdaxbbabaxaxaxxbxcbadbaxxbdbdbxxxababbxdxxadxcxxbaacxdxdaxbxxbdbxbxbxaaabaxaxxcaxbadxxbddbbdabbbdadaaccbbbccdabaaaaxdaacdabbdbddbbbbdabbdbaadaabcaabddaaacbdacacdabbacdbdaaaacxxbxaxxxdbdbxdxxcxadaxxdxdbdxacxaxbxbdaaaxxaabxbxxdaacbdbdbdaacabcaadbxxxxadxaxbaxxxaxaadaadxxdxaxadxbdbadxxaabdaaadxdxxdxxabxdaxxxcddaxbxacbcdbddadacddaaabbabdababbacccbbacbdbbdbbdabcacdbbabxdxxxaxxdbaxxbacaxadbxbaaaccbbaacbaddadbdbaadaaabxacbxdabxxabxxcaaxxaxdbdaddaababdabcabdbadbaabdaaadaccdaxxdbaxbxdxxaaabdxbbccxbbdbxxdxxxxbxcaabaaaacdbacdbbdabbabdaaaaaaxaccxddbxacadxaaxbaxxbbbbdxxbdxdxcxxcxaaaxcdaaxxcbaxadaxxxaababdbbdacbdabdacaaaxxdacaxbbaaadbbbacdbdbdbbdadbadacbdadbaxdbxxaxacdacaxabaaddbcxxadbabaxbxaxacdxadbbcxxxdaxdxbxaxxaxadbdxxxxaxbxcbbxxadxaaaaaxbxxxbxcbaaxxdacdxaxaxdbdaaaacbxaxcxadbdadbcabbbabaadbbbdbbbdbdbdxxbxacxbddbcdbdacbbbdbadacbbcbadbbaxxaadbbxaxaaxbaaxxxxxadacaxxxdxaaxxxxdbxxxbxbadxxadacadadabaabaaddadacddbaadbaadaaaabbadbaaaaaacdbbbbcaaaccbdabbccbdabbdaaadadaaaabacdbbdacbaacababccaxabaaxxxbaaaxxxxdaacxxxdbacxaaxadabdbxbxbaadxbxdxdxdxcxaddxxdacxacaxaxcdaxadxdxacadaadxadxaaaddaacdbbadbbdabdacxaaxabbdaxacadaacdabaabadabadbacbaaacbabbaxdxxxddbxxxcxxxdaaadxbaabdacdaxxxxxdbbddxcxxabdacxadxxaxbxaaxcxbdbabxbxbbxcxaxadxaxdaadbddbbxxacxaxdbxaddaaacdbaaadbdbaccdaadadxaabaaxcxcxaxxbxxbdaxaxbxxxbaxaddxbxbaxaxbdxxbdxxaaxxdxbxxcxxdaabbxadacbxcxaxxxxabaxxdaacxaacxaadbaxdadacbbaabdaaaabaacbdbaacbabdbbaaaddbdbxaxcxddbabdxacxxxacxacxxaaxxaadaadaxxxxdbadbbaccdaabaaacbbbaacacxdxxbdxaxbxdbdaadaaabbbaaccaabdbdbadaadbcaabaaadaaabaabxxaxbaabdbaaccbabbbaacdbccaaxdacacbabxxbxdxbadaxbdxxbbaxacadabaabdbdbadbbdadaaaacdxdxdxxxbxxcadxacxxxcbdbdbdbbaaaacacdadbbaaaaadbdbaaaaxbxxadxbcaaacdbcbdbdaacddaadabdbdxacadabcadaaacbdabdaaadadbdaaaxxxaxacdaacbdaacdbcbdaaaaxaadbaxacaaaxaxxxdaxxaaaxxacxabbaxaxaacdxxdadaacbbbdaaacacabacacbabcaaaacbadbacddacabaabdacbaaadbbabacaaacdbadbbddacdbcabacaacbacddbdadaaaaaabdbadbabaadbabbdbabddadacdbbbcacdbacaacabdababdbdaadabdaabxxabaaaaxxbaacbaaadacaacbbacbdbababadabcacacabaaacbdbaaadbbdbadbbabacbdbcdacacdaxbxcxxcxxbdxdxdbxdxxbacbaacdbabdbadbcdxacxxxdxcxxxdxbaacbddadaaaaaadaaabcxxaxdxdababxdxcddxbacbcbbabbbbababdbdacdadaaxxaadaxxxxbbxabxaadxcaxaxcxxaxxaxacabdbbdadaaaaaaaacaxbabdxxbxxaaxbxxxaabcxxxcbadbcxxbaxxxadxaxxxaaaadxaxdbaadxxabxxbxbcxacxdadxacbxxbdxxxxaadbcdaabdaacdabbbabbacbabacbaaaccxaaaaxbxdbdbdacaaxxxdxaaxxxdxcaaxxaxdadbdbdacbdacabdbdabxxcxxaxbbdbxxxxbxdaxbaabdxaaaaaaabaabaabbadaaadacaadbadbaxbadxbacaccdbaaacacdaaaaaccbddbacdbbbacabdbaacdadaadaadabcbddaabbbaaadaadabbdadaaacdadbaxxxaaaaddaxabaxxacdxxxxxdabbxxcxxxcxbdxcaxxcdbxcxdaxdxbbaacabxacbdaaacdaadbbaacbdbacaabdacacbbdaaddddacxxdxxxbaadxdabxadaababacdbbdbdbacbacacdadbaabaaaaababdbdbdbdaaaacbxaadxbxcbbadbbcdbxdxxxxcdbxabdadbbaacdaaadbcbddbaddbbdbaddbaaxxxbddaaxxbadabbcabbadbbacdbcbabbbdaxaxxabbdaaacdaxaaccdabdaadbabbaadbbcxxdadxdaxxxxxdaxbabbxxabbxaxbaxcbdacxaxaxxdxaaabdabacxacxaaaaaxdxxdaxdxaxbaxdacaaadacbdadbcbcbabdbcbaabbbdxxaxacxdbxdacxbdacxbdxabdacdbbaabcddabaaddbabdbdbdbcbdacxxbxxcbbbxxabdacxxdxxacdadaaaabdbdaaabxxxbaaxdbbacxbxxxbxdaaaabxxadbxxaxxxxadaxxbcxaaadaxxxxbcxacxaaxdaaxxxdaxaaaxadbdaaaacbbdbcbbdbacdbaacxbxaaxxxaxcdbdxxddaabcbdabxbxxaxdbxbdxxadaxdbxbbabxxcxxaxbxdaabacaaaddbaadbdbabbabaccadadbcdbxacaaadacxxdxxaxxxabaxbdbbaxdadbbdbaaaacacaacbaadaabdacdaaadadbacdbdadbdacbddadaccdaaabdbdbadadbbadadaacbbaaaxxxcadbxcxaccaxbxbaxaxacxxxxaxdbaaxaxaxxcdbabxxdbacacxabaxababxdaxbxabxxadacxbadaaxxxxccbacxbadxxbxabccaacaaaaababacxbxbxaxaadxdaxaxcxxcabxxaaaaxxdxxxxaxdadacaaacdacacbdbcabdbbacaabdaacaadabxbbaxacbbacbaaaaadbaaaabdbbbcabdxcacxdbbbaxdaxaxdxxxxxcbdbbbbcbxabxxbdaxbaxbxxcxxaxcbaxxxbabbdxxxbxxxbaaxbaxxabdxaxxxbxaxaxbxxxaxdadxaacbaaaaacbbdaccaaaadaaadacbadxxaxaaaaxbaaacbdabacadbbdaabdbxxacdadadbdaacbbbbacdaabacdaadbdbcbaaaadbdbdadaadababbcbbbdaaababdbdbddbdbbaaxddbabdaabdbdbdbbaabbxaaxdxxabxbxaxxaxdxbxbaxxdaxcxaaaddbxdbdxacxbacaaxadacxdaadbaaxxaxaaxxxxaaxdaaacxxbaxcaxaxxxxaxdbdbxcdxxcxaadbbxxaxaaxxxxxbdbbaaxxbxxbxaxxadbdxdadxxxbaxdxbdxacxbbxxdbcxaacabaadbbbdbdbcbadbbcdbcaaaaacdaacbdbdaaaacbaacbdacccaaacaaaabddadbdaadaaabaaacdaacdbdaadbdacababbabcdbbacabbbdbbdbbbadabdadacbaadaacdadbdbcbbcabdadaxdxddbxcbadxdaxcbddxxaxdacxadbaccaaadabdadadbaabacbbadacacdbbdabdaddbaaacaaxaacxacddbabdabddabdadbacbbdaadacacbaaaabaabadbdaaaaacbaaadxaxxbbxdbxacxdaabdbaaxaxaxaaadxdxxxcdacbadbxxxxbacbdxxabddabxcxxdaddbbabaaddbbcdbabadaaabadxdxaaxcabxxxaxbdxcdbaadbbdabadbdabacdbbccxaxacaxaacxaaaabaaddbddabaaddacbacbbcacbacbaxccbaaadbdbxcabaxxacbdaacdbdbaaababacdabacxaxxaxdxaxxdbxdxaxbaxxaxbdaabdbadbbdaxbdbdxxxaxaxabdbbbcxxxxxdaacxaxcadaxbdaccbxxbddadbdbxxdxcaacaxaxdacbxxaabaxbxxdxdbxxxaxbcxacdxaabbdbxxbxadbxbaxadxacxxxbxxxbxbxxbbxbabbabacdbaccbabadacdbcbaxcadbxbcxdbxbdaxbdbdaxxxxxxxcbaaxxbaxbaxcxbbddxacxxdaxxxacaabxxadadbbaxaaxxbxxxxbbabaxdaaaaacaabbbacaadbbabcdaxcdbaxbxxaadxdxcxdadxaxdxdxcxxbddxddbaxxbdxxadxdxxaxxaxaaxaxbxaabdadbbxacaxbdxxxxxxdaxaxaccxxaxxbxbaaaacababdabacbbacxxxacadxxbaabbdaaaacbaaabadaccdbcbaadxaaacacadbdaxxxxbadabxxxbabxaxdaadadaabdbbbbdabdadbbaaababaaaxbxxaaadxxccdxaxxxadabxbbacdadxadaaaaadabbbcxaabxxxbdbaabxcxxabxacxxxxbaaadaxdacbxxbdbdbbabdacaabbcadbcdaxxdbbxaacaxcaxxxbxxxdxbbxxbdaxxxdacxaxxdaxadacbxaxbbaxaacdaadabbbaddacccbaaabbacxdaaxcxaadacaabcbcaacbbdaadaaadbdaxdaabbxabdxxxxadbxbxxaxacdaxddxaxaxdaxaxdbxxxacdbaxaxbdaxxxbxaaxbcbaddbdbdaddaaaabbacdbdacxacbcabbccbbddabdacaaaxbdbxbbaaxdxxbbcdbdacadabaabdbdbdbaacdbbadbbdabaadbxxxaxdxxbdadbaaaacadbaadxxxdxaxbcbxxbxcxxacbbbacxxcbaabcbaadbcbdbddbdaaddbdbxaxxdxacaadxxxbdxaxdxbxxxddaaabdbcbcbaacbdacdbcxcdaacbxaxdxdbbxabxxxdxaxcxbbdxxxxdxxabxdxaaxxxxbxxxaaadbxaxaxacaacxdxbdxxxxxxxdbcaaxxbdacbbabaadadaacacaaaadaabxaxxaxdxdxxxaxaxabaaacdabdbdbdbaaddababadadddadbbcaaadabbdaaaccdadbdacdadbddbaxaaddxxbxddbaxxxxadbdbaxdaxbbdbacadbdbbdbdaacbcdadbbdababaxxbcdxxbxabxbdxxbbxacxdaxaxxaadxaxaaadbdbabacadbbdbdaabdabbaaaacdadacbadacdbdaxdxbdaxaaabcxacaabacccdacdbabdacbdbbaabccbbacadbcbcxcaaxaaaaadaxaaaxxddxaxxbbbxcbdacxxbxdacxbxbbbxaxxaaxcdaxxxabbbddxbxxbcdacaabddbbdddaaabdbbbabbdbadbaacbacdxdbxaaxaaaxbxxxcxdbaacxdbacaaacbabdadabcbadbaacdxdbcdaxxxbbxxdxdaxaxxaccbdabaadaacdbabadadxxbadxbxabxadacbbbacxcbdaxbxxcbdabcdadabdbbacabdbdbbbdbbbaaaaadabdabaaaaaaxxcxdxxxadbdxxdbdbxxdaxdxbadaxaxacxacxdaxbcdabaacaxxxxbaaxcxbbxaaacaxxbbcdadbdbdbaadbaacaaacdaxbxxxxxxbbaxxcaxbaacxxxxcbxbaxxxabbdacabdacbbacdbbxaaxaccabaaacdadbacbacadaxaxbcxxxbxxadxxcxadbxxacdbacbxadbdxadaxxccabbcabdaaaaccdbcadbdbdbcaaaabxxbaaxxxbadxxbbbaaaadbadbadbdbabaxaxxadbxdacdxdxadaxbcbbdadxaxaxadxabdxbxaxxcxbxxbbxxxxxbaxxxcdxxcdbabaabbbdbxxxxacxabbaxaxxxaaacaadaxxadxbxxaxdxbbxdaaaxxdxaadbxaaxdbaxxbbxxbdbxxxcbdbbxaaxbddbdaaaadaaaadabaacaaaaaddacbccbcaabdbddacdadadadacdxdaxxabxaaxbadacbacdbdbbaacaacbxcbxaxbxdaxcadacadadabadabacbaaaacaaxxxxxbdaxxaxacxaxaadxaxdxbaadbbxacxbxdbaabbbdabdaacddacbaaxbxacdxbxaxxxdabbadbdbdabadabdadaacadaaacaxxxacbbcxbxbbxdxcbxaadbbdbdbddbadbcaabbbbaaxaabxccxxbxbxbbacxxbdaaaddxdbadadababacbdaabbdddxdaaabdadaddbdacdbbbdbcbabadadabdadbbbabaadbaaabaacadabbbcxbdxcxbddxxbdbxxdbxbbddxcbaxxacdxaxxxxaxxabdabaadxadxxxdbxaacdadaacaaaabdbbaabbadbaaaxxadaxaacdxxbdxxdxcdaxaxdxbaaxbcaxxbxxxxdbxxdxxbcaxxbadxaxabadxxxaadxxbxbbdbxbabdxxdxbcadbxxbacbaccbaaacacbadaaaabaaxxdxabdbaxxxdxcabdbaacddbbdadbaabbddbacdacbadbadaxxdacdbdbcacaddacbaaaaxbaadabaxbbcxaxaxbxaacaaxdbaxxbabxxaaxaxdbdxbaxbddbadxdadxaxxxdabxxaxabxxaaaadbabbdaaacbdbbaaaadbcdaacaaaaaaaaadbbcxaacbabxxdxabxxbaaadbccbxxxaaaxbxbaaaabbaabbaaaacabdadbbbabdbaaaabbaabbdacxbxxaxaxbxdxcbbddbdbaaacbbxdaxbxcadaaxaaabdabacbbdbddaacaxbacbxaxxxacdaxxxxbdadxcbddxaaadbdxxaxaxbxdaaxxdbaaadaacbddacdadbbdbbbacdadadxdxadxadacxdabacaaaaaacdabbdbbbdacbdadabadabadaxbcbxcxxacbxadacxdaaabbbcbabaaaabdaabdbcacdaadaaaacdbacdaacadbadaaaabdadbabdaacaaaaabadacddbdbadaacbbadaacdacdbcccdacbaabxaxdbabddbdbdbbbacdaacaaaddaaaxdbbdxcxdxxxaadacabadabacdabbbbcdxxadaadbdaadabdacbbcbbbaxacbxxxxcxxbxdxbdacxcxbxbxbaadxxbdabdbdaxdaaxxabxxxdxxabxbxxxaabacaadbddaaaacdaaaaddacacbaaaaabaaxcxxbxcdbxaacadxaxbbbbadbdadxxxaxaxbdxdaadbaxxaxababxbaaacxxxcbaxaxxabcxxdxdxxaaxxxdbxxaxxxddxaacacdxxcxbcabaxacxaaxdbxxxxxxbbxxbaxxbbaadddadbdacddacdbabbdaaaaaaaddaddbcxxaxaxxxxxxacbdaxadxcdbxaxxxbxxdaacaxdxdaxxxbbbdxacaxacadaaaacaaaacacdbaxxadxxxdaxdbxxcacaadxxxccaaabxxaxbbdxaxaxaxacadacdaaadaacacbacdacbaaabbcbbdaabdbddbaacaabbdadaaaacabcddbaddacabaaadbdacbdaaaabdbbcaabdxaxbxxabaacbbdbadabbaaaabaxdbaacbxbxxdbdbxaaaadbdadaacaadbdbdaabaadadbdabaabacdacbaacdacdbabbddacbdbadabcbbbcxdxxadxaxxxxbbbadadaaxaxcbcbbdabcxaaaabdacbdadaaacddadbdacdaxaxaacbcdacxxxbxaxadbdxbbbdbabaacbaaadaadadbaacbaaadacaacbdaabbadbdbddaacbdaaaxacdbxacxacaxdbxcbadaxdxabbxbxxaxxbaaxacdbccdababdbabdaaaaaabbaaacbdbcadaaaaxxacdbbxxdbbaxbxbdaaaacaaacaaccbdbdxxxxcdxxacccbxxacbdadabdaabaabbbcaaxadbbdacdxaxabxxxxcbdacbaabaccadbabcdadbbxxxacadbxaxxxdadbadaaaabbaaabbddbcdbaadbbxxxcdbabbaaabcaccccbdbcdbbaacbbaxaxbbxxaxaaxxxxaaaadbxbbbbadbdbbadabxxxabdxaxacxcxaxbxaxdxdbadabaaaaacdabbcbdabadaxaxxxaxaxaxxxbddbcbdbacbabbbababaddaaadadabdadxdxabaadadacaaaabdaaacadbacdbacdaaadbccacbacbddaacxxbxxbbdxxxxxxadbaaaxxacbabxbbdbdxbdbaxaxcacdaxxbcbaadaadbabdaaaddaaacadbadaaaaabxdbxbxxxabxxxabaaxxaxbdxadxcxxaxxdaxdxdxxbxxdxdadaxbbxabxaxbxaaaadacbcaaacdaabacbdbxxxcbaaaxaaaxbxbxxxxdaxddbxcxdacxacdabbadbaxcxdacdaxaxadadbaxbxxbxaxdadadabdaacabdadaadadadbdbaaaxcabdbdbcaaddaaaadbdbaddbbbacdbxdbxacbdxcxbbxxxxaaxadbabaxxdbbdadaxdbxxcxxdbxdxbdaxaaxadadbxdaxxbxacxacdxabdadaaacadabdacacdbbdaaacbaadaadaadbabaabdbxxxadbadbxcccxadxxaaxcdxxxxadadbdbdbacbaadacbcacbdadabdbbxxxaaxbdaxcdxaabxxxaaaaxaxccxxxxxbbadaaxabxaxxxxabxxabadaacdbbdbcbbbadadacxxdaxbaacadbacxbdabacbcaaacbdaaaacbdbaabadbadbbdbdadbacadadbdaacbddaddaxaxxxaaaabacdacbcaacacdbdbababbaababddabbdxbabaabxbdacxbbxdaaaxaxxxacbcbaabacaddbadacabxxcbacxbxaxbxxaxbacbadxxbdbaaccadbacdabdbcdaaadbbaaabaxxabbaxdxbbcaaaxabxaxxacdabdabbacadabddadbaaadabbaxcadbdabdbxbxacbxbxaaxxxaacxbadxaaxddaadaxacdxcxabxxaaxdaxxaaxadxbdbbdaaadadadaacacbaaxdxxaabxdacbcbdaxbaccdabdaaxaxxbdacaaacbdaxaaxdabbadbbabdaaadaadaabdaaacbxdbdaxaxabdabbaxadxxxbacxdbxxxadbacbbdaabadacbdbacdadabxbxdaaxbxacxbdbabbbbdabdadbbadaaabdbbaccbbacbcbcxxdadbxaacbbbxxxxbdxcdxxbaxdbxadxacxbaacaaadbdddbbadabcbdadbadbxxbdbacaabbxxbdxbxxdbdbdaxbxxxddaxaxacdddbbbcdabadbdbbddbabcbdbccacdbdbbdabbdbbaaddabadacbcaaadaacbbxaabbxxcxddaxxdacxxdacxaaabcbxxcddxxxacbcxadxacxaaxcadaadxxxxxdbbaxcbdadbaaacdadacadbcacxdxxxdxbdxaxababcbdbbbaaadbdbaadbbacdacccadbxbxxcdaxaabadxbcbxxadbxbaxaxadbxbbdaxaaaaaxaxxaxaxaxacacacbaaxbxbdaxxaxaacxacbaxcbxxacxcdxbxxxxaxbacxxdxxxdxaadxcdbcxbxbxxbdxxaxxxxabacbacacbdaddaacbdbbcaaxcbxbxxacaxadbxadaxccbxbdxcababbxbdxxaxxxbaaxbxcaabacxdacxaxaababdxaabadaxabbxxaadaaabccddacacaabdbbbxxxcbadxaxcdxxbxbaaxxdxxxdxaxxaaxdbabacxbaxxcbcdaxdadaadbdaaaabadaacdbabdbdbddabadaxbaaaxxbabxcxaxbxaxxxxaxcaaxbaaxxadxcbxxaxxaxxadaxbdaacabaccdbaaadbbaaadaaxxxbbaxdxcdbaxdaxxabaxaacdbadbdxxxbxdbxxxxxxbddacxxdaxbxbbxbxxaxdbxxxbaxabxxdxcdbcxddxcxadaccdadxabxbcbabdbbadadbdadbdbbacbccbbbadbxxbbacbxxbaxccdaccaaabdadabadbdaadadabxbbaaabxaxbxcbbaxxdadaadaabdbdacdacabdacxdbdbddxbxcdadxbcxadaxxxadxcdaxxxdbdbxaxdxaxxxccaxxaxaaxbddaaaxxxbxxdxabaccabaaadaabadaadacbbdaccbcbxaaccbxxacacxxdacbdbaaabaabddacabdbcdaaaaadabaddbcadaaacaaacaaaaaaaabaabaaaadbdbadaabbabadbaxabaaacbbddadaabcdabcdadddbaabadbdbdaaabbadxxaxxxxxdaabaaaccdbbbcccaaadabcaaabxxaaccbdbddbdbabaaaacbabaadabcaaabdxdaxaxabxbxaaababaccdabdbcdbbdacababdbxcxacdabdabdaxaxxadacdbadaacaaaaadxbbdxaxacxxdacbdbabaaaccacdbbadaacbaccabbcbcdbxdaxxxdaccbxxxbdxcxxbcxxdaaxbxxxdaaaxxxcabxaaddbbdxabxabdxxbdbabdacaacbacbadabcccacaacdbcbbbabaacxxaxxxdbacaxadaadaccbddaaadacbaaacdbbcabaabdbaacdacbadadxxxbaaadabacbdacbdacbdaaddxxdxxxxaxbcbadxxaaaxxdbxxxdaadxbdaxcaxaaaaaaccacbdaabaddbbabaaaxdxxxdaxxxacdaddaxdxcbbaaxbxxxddaabcbdaxxbbdxdaxxcabdbxxxxxxxaxaadbdxxaxxcxcxadxdxdxbaaxxcbadbadaaaabdxxaxaaxxxxxxdacdaxdxbxxdxaxxxadxaxaxdxdaxxdxxbbxcxcacbcbadbbdbadaaaaaxbddbdbcdbbdbbdbbaaaaababacccbcaxdaabbcaaadbbaaabdaaaddbdbxaaadxxaxbaxxxbadxbcxbacaxbxxxbaxxaaadbbdaaaaabacbdbdaaxacadbxxbaxxxxaadabadacdbdaddbdacdaaadbacdaxxacxxdxaaaxxxcdbaaxaxaaaacxxdaxxbaaadacdaxbbxdaxbxdbaxaabaabaacadaaabdbdbbdaaaaabdbbdbdacdbdbaabacabacxxbadxcxxxxadaxccxxdbxaabcxxxacdabaccbacbdaaaacabadbaaaaaaacdaadabcbaaxadaxbacxdaaaaxxabbbacdbdaabdbcdaababbacaadbxdacdbxxdaaaaxdxdaxxacxaaxcxaxaxbadbbdbdbcbdaacdbdbddbcdbacaaadbadbaadaacadaaabcacbaaabaabxaadaaacbadbdaacacdxacbxbxxbcaaxxxxdbxbdacxcxbbxdxaxxxxdadaadbaaabdbcacdaabadbcxdxdacxabadxdbaxccbxbxaxaadbcbbddxaaxxaabcaacbbdadbdababdaabaabaaacaaaabdbacaddabcddbxbbxxxcxbxxdbcaxbxaadbxcxxbdxdadxxbxxxaxabbbdbacabacabadaaxxxxxcaxbabxbdabadxacxxbxaxbxdxabxaxxxxxaacxbxcxbxbdaxdaaxacbcacxdxcxbdaaacadaaaadaaxacxabxdxdbbdaxaabbxabbbadadacdacdabadabdbacdxaxdbxadaaxdaxxxaxxbbadbcbxxxdxbdbddxxaxbxxxxdxbacxxadaadabddaadbcbabbacaaabxbcaxdaaaaaaxdacxxaxxacxbxxxdbxadbcxabaababcbdbdbdadbdbdacdbdbdbxxcbxxbbxxxaaxacxxbxbbxxxdbcxbadxxxxddadaxxdabxxaxdaabdadbaabadbabcdaccxbbcabaadaaccdbbddbdbacaacbabbdaababbbacbbcaabxxxcadaxxdadbdaxxacxxdbxxdxacdxxbdxbxacaxxxacxdxxxcxxxbaadxxxaxxcbbbdacacdacbdbdbaabccabdxxxabxxdbaaxbbddaxdbdxabdbddaaacaabacabbdbdaddxaxaddxabxxxaaxaxabbxbxaxxaaxdbxaxxxaxxaxdaxaaxacaccbdacaacdbaadbdbdbbdaaacdaadxdacadbcbadacdadbccacddbabdabdadaxdxaaxbcdaxdbdxxaxaxacxxxdbbcdxxcaxdababacbdbabadbdaaaaadaccdabdbdbabacdbbacdaaabaxdbxxxacbaaaxaaxaxxdbxdaaxxxaxxxaxacdbdacabaabaaacbcbadaacaxbdbbaaabdaaaaacdbdaabbababbabbcbabdbdacbaxbcabdxbbdxcaaxdaxxxbxcbacadbadabbdbdbadacadaabbxxxxaxbadabaacaaddbadaacaaadbbbaaaacdbdbxabddaxcdbxxaacaaxdxdxaxxdbdbdxabxxaacxbxcxbaxxdbdbxcbxxdbxcacbcadbdbbcbdadbdadbdaaxaacabdaadaadbbdaabbbacbababbbxbxdaxaxaxcxxxccabxdaadbbbxacbxaxcaaadbcdaaaaaacacbbdaadbcaacbdbbcacddacbdbaabdadabbaaaaadbbdaxxxxxxaxxccbaccacaabdbdacbacadbdaadbadbaabaccadaacbcbbdabbbdaccacbdbabdadbacdbxxdaxaabcaxxxbabxxxaabdxxdxabxcbxaadaxxxacacddaaadadbaaacxbcdxaxbxaaxdbxxxxxabbacaabdadadbacbdbacabdbdaabxdaxxaxxdadxaxbabaxxaaxaxaxxbbxdbxacdbaacdbccbbaaaaaababadxbxbadaxxaabaaaxbcbxxxcdxdbxxxxdaxbacaaacbadacbbdbacaxxbacdaaxaabcxxaaaxxxaxaxbxxdccdadbadbdbbbbaabddadbaaxdbxaxbacdxdabaaxcxxxbxacxxadadadbabcaddbdadaxxbcaadabbxxdbbaabaacababbacbabdbbbbdbbbcbabbacbabadbcaddbdxacdxxdxxaxxdxcbaxcbabxxxadbxadaaxacxxbaxaxaxxbdxxxbcxbxbxxbxxdbxacxxxbbxaxbacdadbdxacxacaxxbcxbxxxaaxxaaxaxbaxxxxbadaddbaxdbacddacbcabcbbdbbdbbdbdadbabbaadbbbcabadacdacbaxcbxxaxcaxcdbaxaxdbdbaadabaccddabacbcaabaccdxabbdxxcdaacccbaaacdbaadaacacbadaaadbbbacacaabacddaacacbxxxxdxdbxxcbxadaxaaxadadaxxxxadaxxdaababbaaaaaaadbxacbabxxxabxxbaabxaxbxxaxabxxaadxacbbbaacbdabbdaadaddabbddbddadbdbabdadadbbdaabbcaaxadxxaxxdaabbaaabadabcbaadbdacbdbaxadxxxdbcxdxxcxaxaaxbaxbacdxbxaxxxaaxbxaddaaaxaaxdaaabaaaacaxxxbaxaxbxabxxdaxbaaxxxbacxdxdbbaxaxaxaxdxdacxdbacdbbxaxaaxaxxcdxaaxxbxdaxbaaaccdacdbddadacdadbaaaaaababdacacadabaaadadabdbaaacdbbabaccabdbabcaadbdacaaaxdxxxxxbaxxxaacxbxxbxdbxaaacbxxxabxdxxxxbxbbadbdaacbdadadaacbbdbbaaadaacacdaaxxcxaadbabxdxdbaxaaxxxxxddxdxacbcxbdabaadadaaadbabddbabaabdbddaaxxdxxdxxabadbxcbadbdacaaaadaccdacdbadacbbdacbaxxaxxaxbaxacxbcxacdxdxcxxbxdaxxbxbxdabxcbxxdxbxxxxxaxdxdbbabcadbaddbaadaababaaadbbxaaxxbabbxbxbxxxaxxxbbaaddbabacbbdbacccaacdabbddabdbacbaaadbxxbaxaxxcddbaddaxcbdacbacdababddaacbbdabaaacbbdbadbaaaaadaaadbdaacdbacdbddbaxbabaabaabdacbaadacdaabaadxacbcxdaaxdbdbxxadxxxbadaacbbacccdbcdacbaadbadabbdxbdadabddbcbaccadbaabdabacacabdabacaadabaccbbabdacabbbdaddbbdadaddbdabadaaaddbbxadxxxxbxaaaacdabbdbaabaabdabcbadxdbxaxxcxabdxxaxxxbcxxddxxadbxaxababbxaaadadbdbbaaaaaaacdbacdaxaxxbxxacxxaaacbbxxdaxxxbaaxbaxxxbdxaddxxaxxdabxxdaaaxbdbbdabaaxxaxxaaxaaxabxabacbabaxadacxxxxbaadadxdxxaxxaxacdbdxxabadbbbxxdxaaxcdbdadbabdacdacaaadbcaaaaaacbaaacbdbadbdabcaaadbbacbaaaaaabdaabadbaaxaxaaddaabacbdbbcbbadaaadbxbdaxacabbbbacabaccadaabaabbdbaacxcbbaxxdbadbxdaaxcxbaxxxxxaxxaxabaxcbdacbcbbdbacbbbddadaaxdaaxbdbabxdbbxbadadxxaxxxcaxadxaxxxbaxacxbacbdbbbacaaccabbaaadbdabdbddddbdbbbabcbcacbdaxaxdaxxxbbbaabaaaccdbbbcacdbddacbaaaccbdadaacbabbaaabdbdadaxdxaabxbbxccxxadbdxdaaxxdaaxxxaabddbxaxbxxdxxbbadxxdbdaxdxxdaaxcdxaaxaxaxcxaxxdxacaaxbacbacdbbdbabcdbadbcbbacdbaxxaaxxacxxxaaabdabacdbacdabdadabadacxxaxaxabcadbaaabxxddxbacxbdxaxxcadxacxbxbcaacbbdbabdacbbdaadadaaxbaxadbacaaxxaabxacbbcxadaxxaaxxaxxcxcxaxaaaxdbxaadbdacaabccbdacbddbdaabxxxbxbdaaaxadxxxaaxaaaxcdadbadbaaaabbacaaxxdacabaabdadadacbdbaaabbaxaaxaacbxbdaxxdbbxaaaaxxdaadbaxxbdxdxaaxxabxxadxcdbcaaaaaaaacdadacbaddaabbadbdadxaxxaaaxxaxddbxaxacaccxxxaxdabdaabbaaadabddaacaabccacadaacababadbddaadabdaaabbadbbbdaaaadabaxxxdxadxccbadaadbbabbbdabdbaacbbabaaacbbbbcbbcbaabaacddabacdbbabxaxadxaabdaaxdacadaaaacdaaabbadbbdbadxxaxdbxacaxaxxaxdaadbabdaacdbaadbacadabccbxxxxaadabadaxaaxxbxdaxxabxaxbcabxxxcbxbcxxxaxxaxbbaxxcddaxaaxdbxxbacbaaaaxaaxdaxbxxaaaaxaaacbbbxaaaxbxxdaddxcxxbaacaxdxacxxbxxabaabdacbddaddabdabacbdadacbaaabacdbacbacbbaaaaaxxbbabacxbcbxxcadxxbbxaabdxaxadaxbxxcxxxdabxcccadbabbbdbcdabdbaaxaabadaaaddbaaabaadaacaabdabxaadxbxxaxxaxxxxaadacdxbdbbxaacdxxxdaxbxbdaddxxxcdacdxxbxadbxadxxaxxcdbxdbabddddbaabbdbaaadxxdbxbadadbadadadbacbbcabaabadaadacbaaabdabbdacdaadacacdacdbdaadacbaxaxbcxxaacdacdxdaxdbaccdaaaaacbdabaabaxcbacdbdxabbxdbxxxxbaaaxxxxxxxdbaxabcbdaabdbdbabaacbaacacababacaabacdxddabbaaacdaabcbdbadaaabdaaaxbdacxadxxxxxxcbxbdxadacxxxxcbaxxxxbxcxaxxacxxbdbxaaacccdadabadaaadbaaddbabdabcaaabaaacxaxaaxdbbxaxcdbabdbdaaaacdacdbabaacbaadaabcdacxxxxxacxxdaxbxacbxxxbdaxbacxxdddbadabadbccaacbddacdaxdaxcxxaxbxbddaaxdbabdadadacacabcdacadbbbacxaababadbbbaddbacbabdaaaaaaacaabbaadacdbadadbcacbcacaacdadacdabbbcbaaaddbdbxxcxaxbdbadbdbaccdbabcbcddbdbdbadxxdbxxxdbdbaxaaxdaababbaxbxxxaaxxxcbxdaabbcbbaccdbdbcdbcbdacxxaxacbxaddxxxxaabcdbddbdaadaaabaaxxadxbdaaaxxaxdacxxaxcxbabccabdabaadbdbdbcdbbbaxaddxxdbxxaxbaxxxxaaxxdbbbdabxxxxadbdaadaacdacaacbdabdaaxxbxxxxabaxdxxaxxabccxbbbdxbaxaxxddabxxxbxxdxaaadaxdacaaabaaaaadaaacxacdaaxadxabdacbdbabdadbadbabadxaaaaabaacxxaxadbxbxcxaaxxaaxxaxadbaaxaxcxxcxcdbxbacdbbxaxxxcxxdbdbbaaddbacaaacadadaddabaaxxdabxbxbxdbdabdaxcaaxcccbaabxxcbxaxabaaacxbbxbbdbcdaxacxxdxaacdxxdbbdxcbxbbxaabcdxcxbdxbxbbacaaxxbbaaxbbaacaabdabaacbdbacaaxxxacbxxdxaxaaxxacadacdbdaadbbababcdabbxbxxxxabaaaxcdxbxadddxxbxaaccbaaacbadxbbabxbxadbdacdxbxcdabdabdacdaaadbbbabacadbaadxxxxabbxcdaaaaacacabdaadbaacbaaadacacabdbaaddbxxxxabxdaxaxxbaxxbddbaabaaadadbdbabbaaaadabbbdbcbdbadabadacbdbcbddabacabacaabbdxaaxadbxaxaaxaxxdxxaxxxaxacadabaabaadacdbcaxbxcxbxxcxaaaxxxdaacdbaddabcbbdacdabdbxxaxadbxdxaaacbbaaaabdbadadadbdbabcabadaadacaababadbcdaaadacbbddadaaxxxxxdxabxdxdbbxaxxacxbdadxadxxaxxccaxbbaxbbcxxacxcxdabadbcacacaccdaaaaabacaaadbdaxbdbxaxxaxdbdaxcxbccbxxaddaxbxxbddbdbaabaaaabcbddbacaaxxcdbxxaxbxdxxcbxadxdxbbxbdxaxxxaxbxbdxxaacbaxacaxcdaxacacaxdabaxxbxaaaxbcxaxcdaxxxdacxaaxdxxcbbxacxxdxdxaxxxbxcxbbaaabaacaxxacbcaaxaadxabababxxxaacdxxbxxbxaxcaxabxaxxxdxabxbdaxbxadbxacxxdxcbxcxdxdxaaxaxbxaacdbbcdaaxxacdxabxdaacaaxcbacbxaabbdaxaddaaxxbxxacdxaaxdxbaxbxacaxddaxbddxcxaxaadaxdbxaxxadaccxxdbxxacbxaaadbadacdaxaacbacbbbacdabbdbddbdbbabacdbdbdbadxxbdadbacdabacbddaaadaabdabaacadadadbcdbcaacddadaxbadadbaabaadbabbadaaxacxdaxccdaxadbbcxxbdadbdabcdaabadabaccdxaxadaxdbxcbbxxaaaababdadaddbabdbcdbdbdadaadaabdacbbaaaaaaxabacacxxxxxxdxddxacaaxxbabxxxxaxxxbadabdbcdxaccxccdxdaadaxbdacxbbaxbxxdxxbxxxxxcdabdaxdbabcbbbdbxaxcdaxxcaaxdxxxxxxdxacbdaaaaadbadaaaaaccbaaacdaaabacbabaacdbbbacdaddabxxaxccxxdaxaccdadaaaaabaaaabdaaaacacdadacdbccadadacacaaaabdddaadabxxxbaaaaxxxxbaxadabddxcxaaxaacbxaaxdadxxaxaadxaaaccxaaaaxxxbaxdacbdaadbcdaadaccxbbxxxdxaabxbxaxxadxaxabaacdxxxdbbxdadabaaadbbaxxcdbdxxacbcbdabaaxaxxxbdbxxadaabdaxacadadadacbbaddabbcbcxaaxaxcdaxxxxaxxadxbbbbacxaxaxacbadadabdaacbdbbdbddbaxxaxxaabaadbdbaxabdaabdxxxaxxaxxaaaaxdabaxxbxbxbxdxabbbbdxxxaxxdadabxxbbddbxcdaaxxxxxxdbaxaxdbbbabdxbdbacdadbaaaaaaabaadabdabbxdbbxacbxxxbxbxxabaxadxacaxxdbbaxxxaaadabdbdacdabxxxxaxacxaacbbxdxdabdbacbaaacadadabaacdaabbaaaxbabcdbabbaadababdaaacbddaabdxxcacacxxxdxdbxxxdaadbdbbxcbcbabbxaxxaaddxaddbbxaaxccxxddxxxxadadbxcdbdbacdbaccdaaadacdaabdbabdadaaaxacxxdxaxabbdbabaacdabaaacabaacdbbdbaaccbdxcxabxxxbxdbcdbcdadbdaaaaaaacacdbacaababdxxxadaxaaccabadacaaacdaabdacaaabxxcdabxxbxxadaxaabxxaxbbdbdadbbaacabddbbcdaadbdbdaadabbaabacacdbcaabdaaccbdbacdaccdbaabadxadaxbbcaaxxxxaaaabcbaacxaabadbdaaccdbaacdadbxxcxxcxbddxcxcdbdxdbdbbaxdaaxbaxadaxaacxcbbaaccxaaddbdaaxxcxxaxbxxabdaaaacbabbaabaaaacdbcbcadaaaaddbcddbdaxbxxdbadxdbadaadaadbdbbbacdbdadacabaaaaaaaaadaacbaacdabadbdaccbaaaaaaaabaabddaabxdxdxdxcaadabbaacdabdbacdbacbbaaxdaadaaxaaxxdbdxdbxbaxxcbaaaaabdaabaaabddadbdbaxaxdaxdxxcxbxdbdabaxaadaabddaxxxaxdxxbxaacdxxbxdbaxaaabcbbacbdadbdbdaxacxaxbxaaaaaaadabxdbcaxadabaxaaxdaxabdxcbacxaxxbaxcbaxaaxabbbabbxbxxxaxbbxbdabxxababxaaxdaxbxxxdxadaxaaxbxaaxdaxdxxaxaaaxcaxxaaxxxxxxxxcxxxbbbaadbacdaaxxdbxaxxaacdadadaaaaccadabacbcxxdxdxxdxdxcaaaxxxaacaaxxababbxxaxaxxxbabbdaadbdbaaaaaccdbabbaabdbxacbxaaxdaaxbbaacbdxxddxxxacbdbcddaaxaxxdbxdaaacbbaxxbxxdxadbabacbbaacbabaadbccdaxxxaaxbxbcadbcdbaadbbdacbaabababxadaacbbaaadadadaddacbxxbxdbbxcaxaxxxxbdbadaacbdbaababdadbdbaaabaacbcddaaaaabdaadbacadbbbcaddbxbbdaxxxaxbbdxaadbaxxdxabxabxxbxxaxxxbbbbbbdabaabaaadbacdbadacxdbaacdaxdbdaxaaaaddacdabdaaaccdadabdcdadadacaaabacbbbadaxxxxaxcdaaxbdxxxacdbbdacababaabcbdaadbaaabaaaadbaaccabbdbacaaadbcdxbaacbxaxaaxxxxaaxxaxbdxbxxxdxaabxxxxaxaxaacabbxxbxaacxxaxxcbxbcxxdxdxaadbxxxabxadxxaaxdxcbbdxaxxbxxbdxxxcxbacaxxadxcdxccxaaacxxabxacdbdbbbaddbabdadbbacaaacadacacadbcdbacxbaaxaacxadxaaaxaxxxbaaaabxbaadadbdadbbbdaabababcaxcdxabxaabxabxddxaaadacdbaadbbcdaacbdabacbbaxdxaxxcaxxxabxbdxxcxbxbxxbabadbadacabaaadadacddadbadxxdxaxbxxdbdbxaacdaadbabcdaacabadaaddabbaacbbdbxxaxadbcbaabaaaccabadabdxxxaxxbaxbdaaddxadaxxbabaxdxbxbxxbacdbxbxxxbaxaaaaaxxabaaccxbadaabacbadabaaaaacababxaxbxxbddxaxbcaaxaadabdaaabadbbdacacbdcxaxadadbxcaxdxxbdaaxbaadaaxxdbxaxbdbaxcbdxxxxadbaxcbdbdxbxxaxacbxadbbacdabbdddacacbacdbdxcxdxbxxadxxxbdbxaxxxacdbdbdbdxxcdxbbxdaacxacabbdabbacaaaaadaaaaaacaadaaxxxaxxxbdaaaxdxxabxacbxbcxxxcxcbdbxcaxaxbxxxacbdbddbacabadbdaabdadbdaaddaaaabdbbadaaaadaadacaxxdxaaxaxadcaacbdaacdbbbabbaaaadbaaaaddacxbxxdaaacaaabxcxxxabaxxaacaadacaaxcbdxdcaadbacdacbabadbabadadbxcdacxxbaaxxxaxxxdxxdbxxdxxxbabxxxxxdxxbadbaaaxaaaxxbxaxxbbaxbdxcadxaaxdbxdxbdbxxxbacdabbaaabaaacbabdaxbcdxabxcxbaxabxxxacxbbaxaaacdbxbdbaacadacbabdaccbaabaadbacbaaaddbbabadbabxadbxbxxxcdxacxxabbaxadbxxxaxxxdbdbxacaadbbbdbdabdbaaaaacdaacbcdbdbaabxxxddxxxxcabcaabcbaccbcbaadaababcbdbbcbddacbdbxaaxxcdxxxcxcxxaaaaxaxdxxxdxaaabxdadddxxaxaxaxaaaadaxxcxbdaxdxcabaaacdbaaaaabbcdbacbabxxaxbxdxxacdaaabdxbabacadbdadbaacabddbaxxxxacaxacxbxxaxxcbaxbxxxadbadbbadaacaaaaaaaaadbxdaxbxaxxbxacaxxbxaaacxdxxaccxacacdbaaaabaxaxxbabaxdbdacaxacdxaaxadxxaxbxdxaxaaacaxxbaxaxaxaxbxxbbxaaabxxxdaabxcaabadcaababadadbabdbadxxaacbacadabcdaacadbaaaaaaadbdabdbbacbdabdaacaaadabbbcdbaxadxxdbxaabaaxdxaacacxxbxxdbddxaxxxdbxxxdadxcaxxdadacxdxxbxaaxcxdbcdxabdaxaxbddbxcaxxxbxbcbxxadbabdacbcbdaadbabdaaxbaaxxaaccbxbxxaxxxbcbcdacdaacdadacddaaaabacbdbdaaccaacaabdbbacbdabbdxaadbdxxxadbaadaxxaxdxaacxxaxbxxxaxbcxaabdacddaadaadbaddbaaadadabbabxbdxdbxaxcxaxxbdbxxxxadabacaccxxxbdaacdaabbdbbaadbacacdbbxxxxacadxaaxadxaxxaxdaaxdaaxdbxxdxcxxxacdbbddacbdaaadaaabdaaacbacbdddbdaaaadaaadadbbdxbaaaxaaaxdxxxbxacxxxxxbbxbxxdxaxdbdbdbbdaabacdacdbdddabbxxxbxxxbaxdxxacxddadaxxdxxbbxxabxxbbacabxaxadaaxaxxxxdxaxaxxxxadaadacbdbdacdbbaccdaacacxaxdaaabdxbaadxaxaxcxdxxdxaxbxxxbbxxabadadabadabbadacabacdbbaacdbaabcdabcdaabcababddadbaacdaaacbaaabdaabdbaabdabdbabadacadaadbbbbbbdaaaabbaxxadbxbbxabxxxacxdbbdaxxaaaddbcdbdbbabdaaabaacaabbacaabbabbbcacacxxxbcbaaadbxxxxdbxdabaaabccdbaaacdbacdabbadaaabdbabaaaaacabccbccbxxxbaxbbxxdxxxadbxaxxdbxaxaabxabxxadbxaxxacabbbabdaadabdbaaaacbadabbaaaadaaabbadaaxbxaaaxxxbaxacaaxxxdaaxacxabxdaxcaxxabbxaxbbbdaxxxxbbxabdxbdaabbacadbxxxdxxaaadxdxcbxdaxadbxacccxdaxaxadxbabaadbbbaccbababaaaaacabdbxxbxaxaadacxacdxxbbxbaxxxbaaxxbcdxbxdbaddaadacbaaaacxdxabxadbxxdaaxxxdbbbabdaabaacacadaaacdabdaacabbxacdxaadxbxxaadaacxxxbxbbbaaadadbbacbaadadbbabddadadabbbdbccdacbabdabcxdacaxxcdxxxxdbbxdxdbcdaaaacdbbdbabbcdadaxaxaxdxxaxxdaaxaaxaaxbxacbxxbdabxdacxbaxbadaxbabbxcdxdxxabaxdbxbxcxbbxdabddaaxbaxbdbdbxaaxcdbbdbdbxbcaaaxabaaaadbadbaaacdabbdaaxaaaaccbacbdabdbdabcdabdbdaxxddxacdbbdbxbaxxdaxaxdbxxbcaxcxabbbxxxaxabdxxaaaxxabxxcaacxdbcbxxaaxxdaxxbxaxxaaaaaxdabcbaabbbabdddbabcbdbbadbaaaadacdabcabddbaabcdadaabxdxcdbxbdbdbcdaxxdxcdxxxxxxxaaaxxxbaaxacxbxbdxcbxcbbabxaaaxdxcdxaxxbccxaxxaxccaaabxxxaaxdadbbaxaxxxbcddbacdaaaadacdaabbaacdacacdbdbaabcacdaacdaaaabadaaabadbacddaaaaadbaddaabdbbbcbbacdabaacbabcaaacbxxadbdbdbcacdbbacdacdbdaaaadaxdaxbxcdxxxbxcxbxaxacxbxcxbdbxxdaaacbacadadacddabacdaabaaddabaxxbdbxaadbxdbxxxxaxcadaaxxcdbdabbaadbbccddaacbaaadbdaxxabxxbaxbaxxbdaaxxdbxdaxxxxbbxaabadxxxcbaaxxxbaacbbdacbaaabbabdbbbdbaddaaaacbaabbdabbdadaabdddbdaxacbbxxdxadbcadaaabcdbcdbaaaaaaacbddaaaacbxdaxxdxddaadxxdxaxxcaxxbddbdbbxbdaxababxaaadxxabxaaxxaxdxxaaxxacabxdaxbxxdbxbbdbdbacdaaadaaadbacdadaadbaadaaaacxbbdadbxadbxxaxaadxacdxxxxxaacdbdaaxxbxxxaxdxbcxadxxcaaxdxbxbbabaccbxcdaxcadxaxxcaxdaxbaaabddxcxxxdxxxxxccxbxdaxxxabxaabbadaabddacadbcbdaaadxdbadxxxdbxcdaaaaxxxxadbcxxcxxadacxbbabadaacbaacaabbcacdbcabaaacxcadbaxaxxaxdbacdbadaaaadbxxxaaaxdaxbaxaadxdbaaaaxbaxcabdxbabdxaabxxcdxbxxdabbbxbaddbbaccaaaacdaadaadxaxxaxxacaxxdaacdbdacaadabacbddacadacaadaddbbaacbacccaxaaxdbdbbaaaaabbbabbbdbdbdbaadbcaaxdxxcxaxxabaadbcdbdddadaadaaxdacxbxabdaaaacbaccbdadadbacacabadbacbaxbcaxaxdxcbxxxaxxaxacxbxdbxdbdaaacbabaadaaabxdbxxcdabaaccdbabaaacacbabbbaacbabdaaxbxxbadbxbabdbxxabaddbdbaaccaacbaccbxxacxabacbabadbaacacdbdacdacaaaaaaccdbcdacdbbdaacbbaaabdaacadaacdaacbbbdbdbcaacbbabbdaaabadaabbbbdbbadaxbxbxdxcxxxaaxcbaaacdddaacbdadbcacbaaacacbdbccbdacdbdbaabbdabbdadbdacbacbbaabacbabdxaaaxcdxxccaxxxxxaaxxaaxaxcdabxaccbdxxxxdxbdaaxdaxxxbaaxabaxaxdaxbdadxaxadaaxxdxdbaxxbxcaacaadbabaacdaddbaabdxxxaacddbxcbbaccdadbaaaabdaaaxxdxdaxxadbdxaadaaxaxaaaxaaaacxdbaddxdaaaxxdaaadxacbadddbdbbaddabaabdbxaxbxxxcxbdxxxbxxdaccdxaxxcdaxxxacxxaxbxaxcbbxxcxxaaxaaxxxaadxbbxaxxaxbaaxbxxdxcxxbaaacdbbcacbbadaaaabdbcbacabbadaaaaabdaabbxxdbxaabaxxbdabbbdbdacabbdacdxaxbxdxadbdaxxxbxxxxaxbdaadbaxabdbbbdbaabdacdbdaaabdbabaddbxdxxxddxxbbaaaxxaaxxbxdxccxaxxaxxaxaxxaxcxbadacaaaabaddabddaabbdaacbdaacbaacdbbbbdbbaaaacbacaaabacadabddaadaaaaacacbbaaadaaacbbxadxxdxbxxxbdaddaaadxdxaabdaaxxxaabxbaaxxxxaaaacdbcdaddababaabadadbdbbxbadaxcaxxbxaaacdbdxbaxdxbxbdxxxdaadaaacbbbcdbadaacdbaabdbacdacababddaacddabbabxaacaacbdbaadbacdbcdaadbdbdbdbdbdaababxbdaaaacdbdadbabacacaadaadadbdababbdbbbcbaadbaaacaaaaabbacbdacdbdbaabbxxxaxxdbbadxaxdbxabxdacxbxxaddxbcxaxxdxcxdaaxbbabbdadaaaaacdadaadabbdbbdbabdacaadxxdaxaxdacbadaaaddbbdbaabaaxdxdxcxxxdbcdbcdabddabacabaxxaaaabaadabcdacdadabdbcbbabxxaxbdbdbdbbxxbxaxdadacdbacdbcdabaacaaaaaadbaaabbcdbdxaabdxxdadbaabdaadbaadaacaacdxcxxxdxxxbaababaaadacbcabaddadabbdaxdxcaxabbxxxaaadxaaaxaxbaxaaaaaaaabdaaadbdbaddbacadxxbdxbcbabddxbxxbdaxbaadaadbbdbbaaabdaaxaxaaaxxdaxabddbbdbxaxaxbbaxaadabccbccdbaaadaacdaadadaaaacxadbxxxxbxbaxcdacbadabacdabbaaadaaabadaaaaaabaadaaaacbbbbabcdbcdxxxxaaabxaaadxxxxxaxabcxxbxbddaaacbaccbdaadbaadacaabadabcbdbdaacbcaxxaxdxxxaxaxaxbxcbaxxbaxadbbxxaaacbdaadaaadbdbdbaadbacbdaacbaaadabxabdadaadbaadbdadacdadabcaaacxbdxcabdxaxdbbbadxaaxaxbdaxbxxxdbcxcdaadbdbxacbabddbacbbbdaacdbdbacadbacbaaacdxxxbdxaxdxadxdxdaxxbbbadbbxxdaaxaxxdxxbdxdxaabxxxaxxbdaaaaxdaaaabbbbadaacdbaaaadacabbdbxadaxxaacxdadaabdaxcxxxbxabcbaacacbcdbcadaxaxabdxxcdxbacbaxdbaacxaxxxxdaxcxadxdbadaxaxxcxaxdbaaxxxxxxbxadxaaxacaxxaabaadbdabbacaddadbbbdbxaxxaxxabcbxabadbxacdbxadxxaaxxaxbxxxxcbxbcxxxxdaaxdbcdadbaadabccdadacdaaadadbcbadbabdbdbxdxaxbdbxdabcbbxxxabxdbbaaabddadbaabdacdacacababbxdbdbdbbxxxxcxbxcacxxdbadaabxxxxbdbbaxcaaxcdadbxdbabababdaaaadbddbadaadadbadaaaaccbdbxdxdxxxaxcaxcacxbxdbaadbbbabddabcbbadacbacdbacadaabdacaadaaaccbbadbdaaadadabaabdadbabaaaacbaacbddacadababbacabbdbbbdbaaaabbaxdaabcdbdaadababbbdbabxxxaxxxaxbbcxadxxbdbaxxcxxxbccbaxaaxbadbaxxbbbaaaaadadababdbaccdabxaxxxdxxdadbxdxcaadaabaxxxaxaxbbxaadxxxbxbxbbxadabadbaacdaadbbaabcabacxcacxcacabbdaxaabaaadbdabacdbdbdbaaaabbdxbxbxcxacxxdaxabdxabbadxxaxdbxdbdbbxcxdabbdadabbacabaabaacdbdxdxaxbxxxbaaacxaaaaacxxcxxaxaxbxbdbaxxxaaaxaxdbcxxcdacbbabdaadbabaaabdabxaxcxaxdxdaaabxaaxaxxaadxaadadaacbdaaabbddbaadaabdacabacbabcbaaaaacbbbdadadacaacbbcxbdaxbdxxaxxxxxxabddbaababbaadbcdaaabbdabbbadabaaccacdaaababdbacdaaxxxcxaadabadbcdbdbadbbdbdabacdbacdaaadacdddaaacdacbadabdaadbabdxxaxxcbdaadxbadxbxaxxaxbxbxxaxdacaxaxaaxdxxaaxbxaxacaxabaaaadaabbaacdadaacabbaxxxdxadaxadaxaxcxbaxdabdaxabaadxcxaxacxbaxacxaaxadaxxaxdxdbxbdbaadbacbdbddbcaabdacddbabbdbcdabccbbacacdadbdbdbdbdadbddacdxxcxaaabxbcxdadaddbaaaadaacbaadadxbaabxbxbxxxbxbaadaaadbadaxxxbxxbdaabacdaaxxdbadxdxxccbcxxxdaabcxabaaxdxbadbxbaxxxxaxaaabxdxaaxxxbdaxaadxxddxaxxdaxxxxbdbxadbdaadacdaabbbacdabbaacbdaababaacdaaccbaaacbadbdabcdacaadbabdacbdaaacaaaababaacccdaacbcbacxadbxaxxxadaxaxxxabaaxxcbcdddabaaadadxxbxxdbxxaaxxadxddadxbxxbxbxxdxdxxxbabdxaxxbxxbcxdxxaaadxxadxaxaxbxxbxxxxaxxcbcdbdacccbadadadbaaaaaaaxxbaxabdaaaaaxxddxbaxdxxcaxbxxxaxaxcxxaaaacdacabdabdadadaacbbbdacbdadaadbxaacbddacbbbdabbdaacdbbbbacbdbdaaaccbaadbacacbdbdbbdabxxxacxaxaxbxcxxaabdaxbxxcdxcdxbdaaadaaaxxdxxabxadadxxcaxxxbbxxcxdxacbbbcdaadxdxaxaxdacdbabccbaddbadbbdaacdbdabaxdaxbabbcxxaxabacaabadadaadabdbdacdadaaccbbaaaacbdbaadxbxbdxcxaxbbaacxbaxxxxxxacbaaxaabbbdaadadabaabbaacdbcdaxacxxxcaxxaaxxacxadaxcbaabbxaxbabxbcbxbaxxxxxxbxacadaxdbaaabdbbdacbdaacbbabbdacbbacdbcaaaccbbadbaaaaadbdbcaaxcxcdxxcdbxbdababxbxdxaxbxaxxbbdxxdaaxbdadaxxxcxxxxaacacxabxccbdxxaaxxbxcxxacdxaxacaxbbxcxdxxxdxxacxxxacdaabaaabxxcbadbadabaaaaabaaabbbdadacdababadbbxxxxxxcxbbccxxxxaxaxdbacbaababaadbacabdbdbacdadbdbdaacbcdabbbaabdbdbbabaacbaaaaaaaadaaaaaaxaaaaxbxdxabacxbbdxdbxaaxxxxxxabbbxcbaaxdaaxcdxaxaxadxaabxaxxabaaaxxaddxxbaxxdaabbbaxaaaaxaaxaxxbaadbbbabaabcdbdaaabdabacaaaabbdaadadbbabababdacdabaadacaxaxxaxxxxxdxxxadbdaaxxbxccxxxbaadaxaaxxxaaaxxaaxbxbdabadxdbaabdbadaacbbacbaabdbxcdaxcdabaxcdbadaxxdxxxbdxdbbxaxbdaxxxcxbxxacbdadbdadaadbbddbbdaacabccababdbacaaadbcdbbcbaadadbbabdacdabbdabdadadbbdbabbbaacadaaadbdaabdabbddabaddadbbacxxbdbadaaacbbbbcaacacaacdabdaadbaaaaacbadaaaxdxbxxxxaaxdaxbxxxxdxxaacbbadbadaabcddbbacdababadaaxaabdbxxxadadbbcaaaacbddacaabdxxxaaddbbdxadacbxaaxdaxacbxxabbxadbxbxcbcacxdabdxbxxxxxxaxbddabdxaxaxxcacabbaaabaaacaaaxdbaxaxbxbxaabacdacdbadadbbdaadddaxdbxbxxcabaababddbdbbbacddadbbcxaxxxbxdaaabcabdaabdbadbacabdaxxaaxaaacacxxabacxbdbaabbdacbbbacabbbaacbdbadbdabdaaacbdxaxadaacddaaxxdaxcdxaxaxxbdbbaaaadbbbcbdaabaacdadaaaabababcbdbcdacdaaadaacaaxaxbdaaaaaaadaabdbbaabacbbadbdabdbacbacacdadacdababcdacdbcbbaacaadaaadbacbabadadbabcbaaadadbadbddacdacaaaadaaadadaaaddbbbdadaaacaaxddxxbaadabxaxxbaxxdxcxbbbdabdbdbabcbbaadaaabcdadbaadabdbdadbabaddbdxxadxdaddxxxxaacxdbbdadacaacbddacbadacbxxbbxadaddadbaaaaaaadaccbdaaaxbdbxabxbxbaxacxdacbxxxbdbdxxacbxaaaadaaacdaadaaddaaxxdxcxxaabxdbdxbxxxxbxxcxdxxbadbdbdbacbcdaaadadaccaababaaxxaxxxadaxxxcaaxxaxxabdxacdxaxaxadaxxbxdabxbxaxxbaxabbdxxcdxaaxxxbcdabdaadxxaadxxbdabbxdababddaacabcbbdaccxbadbxaaxcdadbcddaaaaaaadbaadbaabdbdbdbdacbababbdxdxxaxaaxcxcaaxdxccxdxxdxaxxdbadaxdxxdxxcxdbxxbbxcxcbaaabxdaadaaaadbdabcaadaacacaxabxxcaxbabbabdbbadaacaaadaaaabdabdbdbbbdadbbbacaaaxxaxaxxbabdbacdaacbdadbbdabababbcdacbacdbcdbdbaacbaxxxbxxbxcaabdacbbacbaabdaabbadaadacdaaacdadadbaadbaaaccbcbbcbaacddadbaadaabbbadbadaxbxxbbbdxxxxaadbxcdxdxbcxabdaxbdxxxaadadaxbaxaxbxbxxxxbdbbaxxdadbbabccbbacbdaacdbbdaacdadbdabxaxxdbabxxxaaaxbxxxaxxbdbaddaacbdbxbxxaxxxccdbxaxxbbxbxxcxxcbacbacbxaxxxxaaxaxadaaadaxbacdaxxxbaadxxaxabbbddbdbacbacaacadaabdabbaaabaabcbdbdadaacdbcadaadaxxxxadbddxxxbabxabacdbdaaadbcdbaabcadaaacbdacacabaadaabcdaacbdaabxdxbxadbcxaxxxbdacxbbadbbacdbadadaaaadadacdbaaadbxxcdxaxxxddbxddaadaaaadbaaddbdadbdbcdaxbbbxxdabcxxbxxxccbabaabadbacadbadaabadbdbbacaadbabacbdabdacbbadaacbbabbbacdabddbdadaacaaacxxabxxbbxxxxbbadbbaabdadaddbdaaabadbbaxxxxbbcdbxxaaacdaaaadaxabxxaxdxaxdxbaxdbaadbxaxxxxabaaaxaxbxbdbxdbaaaacxbxbbxbxxxadxdaxxaxabccxccxxcdaxxxdaxaaaaaxbxcaaaxxadxxaaxabxacbaabaadadabdacdaaaaccaaxxbbxbdbbdbdaaacdaadacaabdabadaabadaaaaaaaacbacdaabbdbaacbbabaccaabaaxdbxxbbdxdaaaddaacaaaacbdbdxaxbaxdxxaadaaabdaadbbbdbdbdaccdxxxcdbaxxabdxdaacbbaccabcabdbabbbdabbaaabaxaxbxaxxaaaacxxaxcdaxbbaadbxdaxxxdaaaxxxcdabxaxbadxxbaaadbaadaaadacababbadxdxaaacdbaxaxaadabdbabbdbbacbaabaabadabddxaaxxbabxdxxcxaaxdaaabaxdxdbcdaxxcaxxdaaacdbbdacaaaadbaadbbbdbdadbbbaxxxcabxaaabaaaadaacdadabdbdadabacdadaaadaddbacddbcxccdbbcdaaacacdbacdacbcdbbbbdbdaabacbbbdacababaacbaadbcadbaaaacdbcdaccdabacbacxxacaxxadxxaxbaxbadbabxxdbcdbdaaaccdbadacaadacaacdbabaxbxbxbdbdbbdxdxxabdbdaaddabaababcbdxabcxxxcbxdaccadbdbccaaadabcbababdbaccbaacdaaadacbbadacdaabdacccacdaccbacaadbaxxcxacadbcxadaadaxdaxbaxaabaaccbbbxbdabaccbacdacdacdadadbcbbaddbdaddabadaaadxxxxcaxbaxaxdxxxbxaxxxbxabbbaxcxxacadbdbxcxaxaacxxcbbabxddxxxxcdadaxbacdbaxacxxaxxxcxxadbxxcxxabdadaxaxxdxxxxxxbdabdaaababaababadbdbaacdaaaacbaxxxxaxaxbbaxxbxacxxxxxxcdadaxxxaaababcaaaddadbdaddbdabccbacdbxdbaxcdbdxxdxaxaacbxxdaaacdxxcdaxxbxbaxaxxacbabdbxxdxxbxaaaaxxxddxbxaaxcbxxxxbxxaxxaxaaxacxxbaaxxxbdxxbaxacxcxadxbxbxbcbaxxxxaaaxxbaxcbdxxacxacaabxaxxcdxxaxcbaxxxaxxbdxxxxbxbdbaxaabacdxxxxxdxadxxxaxxdbbaxcadxdadxxxadxaxxxxcbxxadbxcxaaaaxbddadbddbcdacdbcbdabcbaabxbbdaaxacxbcaaaxbaabaabaaabacadaaacdabaadbcbacdbaaadadddxdaxabacaadabacacbbaaadacbbabbxxcbxccdaxxxbxxaxaabaabbaabacaaaacadacababbbbbdbabbdaaaadbabaxdabxxdbbxbaadaaadxdxxxdxxxbxaacxaaaxxxcdbacacaabbadbaaacdaabdaxxxcaxxbdxddbbaaadbdbdbacdbdbxaacbbdbdbdbccbaadadaaaaaadbaaaadxbdddbbaabbddaadbdaaaabaabcbcdabxxaaxxxdbdbcbbbbbbdbdbabcbcdacxbbbabxccxbaaddaacxxdaaaaxxxaxaxxadxxbaacxxxcxaxaabdaabxxcxbdxaxxaxcbcbaadabbcbbdbdbcbadbacbdadxadbacaaaaaaaacdaaaadbcbxbdxxxxaacdxxaxxaaxcbdaabdbacaadbdbacbdacxbxxbxdbaaxcaxbaxdxxxadbabdaccabdbdacbdacdbcaadaacadbdacaxaaxaaaxxxxbacdacadbcbbddbacdbddbbabdacdbbddbacbddadbxaxxdaaaxdaaaaccdabbacadadaaaddxxdbbaxaacxdaaaaacxxaaxbdxbbxbxxcabxxdbxadxxaxcxxxxxbdbxdxcxaadxbxdabxbxxaacacxaxcxabbcxbxadxcdxacxacaaabdbxxxbdbbdacxxaacdbxdaaaxxxaxxxaxadaaaaaadbabdaaadbdbacxaxxcaxbabxaxxbdaaxxxacdaxxxbxxdaxaxaxabxaxccdabddabdaaccaxxadaaxaadacxxxcxdbxxdaxcdabxxabbcxabxaaxaxddxxdbaxaxccxxdbaaxxdxxxxxcaxadxdbdbxaaxxxacdbadacabddadaaaacdbabaabaaadbdbdbaabdabacacdaabdadbxxxcxadxabaaaaxbxdxbxcacdaaaddaabxxbbaxxccxdaacbaxxaacaxadaaxdadbxacaxaxxxdaaxaxaxdbxxxaxdabxaacbbxacbdxadaxdacbxdxbxdaxxxcdxxbbxddbbaxxdxaacxdxxbxxbxdbaaadaabdacbdbabcbdaaaacaacxbbaaxdacxxxxbcbbcxcabdaabxaxbaxddaabbbcbaabbdacbaacdaabaacdxabdaddadaaaacbaacbacxadxabxxabdaabxxbxxxbabaaxxbxdxxaabdxaabbaxxdbxcxdxadadbxbxbdabaxxxbxxxxdbcxaxaxcbxxxxxbdxdxaaxxadxaaaxbadaaxaaaxxxxxaxxaacaadbdbbdacbadaaacbaxxbacxxxxadadbadbdddabaababbaabdacbbacdbbaaadacdabadadxxxcadxxxxaxxbaxcabaxdxabdbddxxxbcxbabcbbdbaabdbabacbbaaacdaadxxdabaaadbxbxaaxxxxxabbaxaadbbbdacbbaadbdabdbaaaxxcaxdbaaxaxaaabacbabaabdacdaacdadbadabadaadadadaacbdbcdbadbabdbdbadaabcbabbbdaaaacbbdabaaabdbbcbdbcacbxdbxxbabbdxcdxbdbcbxaxbbdbdacbcbdadadbaadaxxbaxbdaaxxacacxaxbdacxaaxxxxbxbdaacbdaddbadbdadbdadaxcxxxcxxcaabxabcbdabdbaabcbbdadbacabaacbbacbxaxacxxxxxaababadaddbdbbbdbaabbbabdabacacbaadbddbaxacdaxxbadxbaxxxxadbaabdbaxaaxxxaacaxxadacddaxxxabxbxcxdxxxxxxaadbacacxxaaxdacdxcaadacxxcaabdxxxdxxdxxxbacxxcacbxxadbaabdbddaadbacbaadbaccdbaaxaxbdacbxaccxxxxxdxdbxbxdacbxaabcxxbxacabddababdacbacaabaadbdacdaaccaddaacbcddbdbxxbxcdacbxxaaaaxdbxcbdaaadaaaccbaacacaaadadbabaaabacabdaaaaadbadadadbdbccxaacxadxddaxxxxxbabxaaaxxadxxbdbacaddabadaaddbcccabdbadbadacbacadbaaaabdadbxxxdxdbxabxxbxxxdabxacdaabacdaacdddbaadaacdbdaaacadababaaabadbacbddacbccdbdadbaxaxdbaxxaxbaxdaxdxbaxdaacddbabaaaaaadabbcbbdbaadaxcdacbdbadaacdaadaadaaacdbbaaacabacaadaddbdbdbadbxcdbacaxxxbcaaaabadbxbxxaxadbbxxxbdadadabdbadbaaaacdxxxaxdaaxcxxabxxxacxabacdbbxdbxxaxcxdaxaxaxxacxccxaxxdxabcbcdbxcaaaabbaacdbbabaabaabadbbbdaaaaaaaaaaadadaabdabaacaxaaxddaxaxxdaaabcxxacxbaaxxxbxxxcdbdbaxdaabxcbbadabdabccaaaabaadbbdaaxxbcbxdxdbddxacxbdaxaaxadaaxbxaaaxaxxaxxxxxbadacdbdbbdbaabbadaacdbaaadaxxbxbbxxbdadadbdbxdaxaxdxcaxaaxbdxxxxdbxdbaaacaadbbaadbcdaacbbbxcaabxaxxxbcdxabdadbdbdbbadacbdbabcdbaaadabbdxxxxadbdabxbxbacxaaxcccaadaxaxaxxxddbaxdbaaaxcbxaaxcxacdaxxxxcaxabxbabcxxabxxxaxxbadxxabdxadxbbbdbxaabdxxbcxbcxbxxbadxxaxbdxxaxccaxxxxbbxbdaxxxxdaxaacaxxabaabadaddadabdbccdbdbacbacbbdaacdbacdaadacxabbdxxbaxdxxaxxxaxcaxbxxabxaaaxxbaaxabbaaxdxxaxxadaxxxxbxddabxxxabxdbadxaxxxaaadaaxaxddbaadaacadbadacadbadaaabaaabbaxdxbdbaaxxbdxxcdxdaaxdbbxdbaadaaxxxabxadadxcaaabdabbaacdadbdacdaxcbdxdbxxdbxaxxxbdxdabxdbaxcxxbdabbaxabxaxxaabaxxxaacaxbxdxbaabdbacddbbabbbdaaabccbbbcddbdbddbaaxxbabdbdaabbdbdaaabcbacxxaxxdaxaxxcxxdxaacbaxbxbabcbdbaxaxxxxxaxcxdbdaxxxaababccxaaxabcbxaxbxaxxbxxxxabbabdbaadaabbaadbdaaabbxdadbxaxdxcdxxdadaaaccdaacdaaaacbcaadbaaadadbxxdbxabxaxbxaxcdxdxxacdbaxxdxaxxxbbxdxxbbxbdddaxxxcxbaxxdababacbdacbaaaccdbbacdacbdaacaaddababdbadbcxxbaxaxcxxdbdbaaxaaxxxxxxdbxxaaaacxxaaxbaaxxbaxaacdxxxxaxadxaxdxaxxxdbdadadbcdadbbcbaadaadbabacdaaccdddaacbcxbadadaaabbbaabaxdbxbadabbbbxxbxxxxdbaxaxdxxxbbxxcbbaccaaaaabadbcaddaaabdadbaababcabdabdaabdbaaabacaacbabaaaxaxddbababdacdaaadbdbaaaaaabbacdabxaaxcaaacxxadxxxbdxdxbxxcxcbdaaxxxbxaadaaxcxxdaxdbaacbxxaxbdxxaxxdaaxbxbadbdadbdbcadadacdbaaaddbaaaaabddbaabdaadabbdbaaaadadaaaabxbacxbdxxcdxacxaxadxacbbxxdxxbxcacxbbcxxxxxxxaaadxbaaaxxcddaxxaaaaaaaaacdbadadbaaadbdaadaaabdbcabadaaabaxxaxcdacbdacxxdbbabxxxabacdadaacaaacaaacdbcdabbacadaaddbxxcbxxbxbbxdacaddbadaadaccbdbdddaccaacdxxcabaxxbadxaxxcaaxcddacbdbdbbaaacbdbdbdbdaaaaabaadbdbdaaxxxcacddaacdaadbabbabadacbbcdbacbdbxdxbxaaacxxbcxxxaacxacbdaacdbdaadaaaaaxdaaabdabadaaabacdadaabdbddaabbbaaadaacaccdbdbbaabacddbacdacabbabacadaabcdacdaaccbbaaaacdbxbcdxbaxbadxaxbaaxdbdbdaaabdbaabdaacbaaaaaaaaaabaaaacabcdaaccbacbdaabbacbdxxxaxaaxxbaxxabaxxxaxbxaxcxxbxxcxbabbxxaxadaxcdbxxxxdbaxxabaaadadbaxxadxbdxdxbxabxaxxbxdxbxaxxdxacxbcxdadxdaxxaaxaxabdbbxaaxxxdxxxbaacxdacbbbxxxxcadxbxbdadxcxxxbdxxdbcxcxxxxxaxdaaabaccbacddbdbacdaaaadbabaxxaxaaccaxaxxxxaxxbbcbxdxaccxdbacdxdxdxcxxxdxxxxxcbaaabbdbacadbccbbabdacbdbdbdacdaacbadbbaaaaaacdaaabaacbddbcdaadbcdbxbaxbxdxaxdbbdbddbxbbaxdxaxxxadaxbaxxaxxxxbxabxaabxcxaxxbdxbdxxbcxbbcxaxabaabdacdadbdbdaacxxaxabxcxxbcxxaaaxdxbadxabxxxacbbxxbaaxabdaxbxxxccdaccbbdbddaaaabaaacacdabbbcbdabxbdxbxaxxxbbcabbxadacbxaxxdxdbxxbxxxxabdabdabdabaabadbcbabaaxxxbaxbaxbxaxaxcaddbaxcxacaadbbadbdbcbdbcacdabbaxaxbxaaxbbxxaxbxacbacxbabxxxdaxxaaxxdbdaacaaxcxxxbcdacacbdadacadbbdaaabacabcaacbaabaacabcxadbxdbccxaxaxxxbdbaaaaabbbaacbabaaccdbbxxxaxaadabxxadaxaabbxaxcxbxxaxxabxcxxxaadxabdbacbcbaadbdbdbbdbacdaxdxxxbadaaaxabbaaccdadaabbdabbacacddadbaaaaadbbbdbadddaaaaxabaaxxdbaxdbxxxbbaxbxxxcxcxbaxcbxdbdxddxxxbaxxxxxaxbbdbdbddbbaaccadbabdbaacadaxaxaxxabdaxbbaxxbadaacbbdadaaacdaccbaaabbbdacdbbabaadaabdaaaaacbdxbxbbbxxbdxcdxbaaacdbbdbabdaccacaabxaadxbbxcdaaaabbaadbabaadbdbdbbaacddaxxxxadxadbbdaxaxxxacxdxdbdbdbacdbbdacabbaaxxdbdxaaxbddaaacaccxbxaaabbcdbadaaaadbcbaaccbdaadacaaaaacacaaaabbdbabadaccbxcadacacabdbddadababadbdaacdacdacaaaacabxaxxxabaxdaacaxcbcadxdxxdxxxxaadaxaaabxaaxaxxaaadbaxbcbdaxdbdbdbdabbdbadacdbaababcabaaabbbbdadaaaaadxdxcxbxbdbdaaabacacaabdabdaaddbcbaccbacbabaabbbbaccbaaxbxaxxabdabbaaaccdaddbcacabcbdbdbxxaxxaaxdxdbxxxxbxdaxacbxxadxbdbabxabacaaaaddbdababaabaaadacadaaabddacdaaaaaadbbcdbdaabdadaabadaccdbadbabbbbdaababdabbdbdaadbbaaadaabbaadacdbdbbxadxxcxxbdbxxaxbbxbaxcabaaddxdbxacdxaadbxbxbabaadaaaadxaxaaabaaxxcadxaacxdxadacdaaacdadabaabdababacdxbxxcxaadabdaadacdbbaaadaaabxaxbcdadbdadbacbdadaaadadaaxbdbdbddadbbaadbabdbxaxxadaxxbxdacdbbxxxxacdxxxxabxdaabbxxxxdbdabdaaadbxacdxdxxbacbxxcxxbxxbxbadbbcxxacbxdaaaaabaaabadxbdxxaaxxcaxaxxaccxbaddaacacbaabaaccaaxxxcxddbxaxbaxdbaacaxcdaadbaabbaaacabadbbaccaaacbddbbaaxbdbabaxdbxxaxabbaabbdaadaccaabdadbabbdaccaadaadbxcxbcddabbddxbdxxxaxaxaaxabbbxaxaxbdabcaacaaaacdadaaaaddababbdabbcdbaxxbxbcbxxbdaaxxaxacbxcxcxbddxaxdxcdaxadxxdxbxdbcabdbdadaadaadadaaddbdbaababaxxxcdxcbdbcbabccacddbbdaaaacbbddxaaxxabaxbabdbxaxbcadxadaaaacaaacaacdxaxabxxxacxxxxxbbdxxbaxxaadbabaabaddbaacaabaaaadbdabxaxbdxbcxxaaaxxbaaaxxxdaxbaaxcxaxbxdxbdbbxbdaxxxxxbdbdacbdbcaaacbbadbbacbadaaaccbacbxacxaxdxadxdxxdbaaadacbdbbababbaaccbabaadacabaadaaaaxaabbacdaaabacaacdaadbacdxbdbdxxdxacxbxbaadbxxcbdaxbacadbaaabxdbaxxxcxadxxbdadaacdbdbaacdacdbcdxxdbaaxbacxxxxdbxxxxaacbxaxbxxaxxxaxadxxdaabbbaxaxbaxbdbaabccdaadacbaaabadxcbdxcdaxdabdacaabdaccbacccaacbdabdbxxxxxdbxbdxaxbacxxbbxxxxadaaacbdaaaacaadbcdbddaaddacadacdbcbabbbdxxxcbdaabcadbabaaadaabdbdaaxbbxbaaxxdabxxxcxcbacdxxxxbaaaadbbaxbxbadabadabdabbabbadacccdaxxbxaaxxxxdbxxbdabdbadxxcdaccbddaaxaadxbxbxbxxxbadabaxaxbbbxadbdbdbadbadabaaabacxxcaxaxxacxaadxxdaaxbxxxacbbcxbaadaaxaddaabxaxcxaxcbxdbabdabacacdadaacdbaadxcdxxdxxdxaxdxcxxadbaabdbccdacaabdbbabbaaabacdaaabacbdbaacbdabacdbdbaaccdacbabaabcbdadaaxxxdxaxadaxaxxxbbbaxxxcddbacdbacdadbacdadaccbababxaxxaxxxacdaxxaaxbxaaaabbxbabaaaadaabbaaaaaaadbacbaaabacxxdbbadaxxcacdabxdaxxbdxacdbxxxaacddaaxbddbxxxadxxbadbdxxadaaaaacdaabbdaaaccxdadaxdxxabadbbabdabcbabdabcbcacddaxadbxcabaaacdaadadacaaaaaaabbadbadaabababxbxxxxdaacxcabaabdbacadbacbdababbdbdaaadaabbdbaaaacabbdacbaabaaxxxxdaaxxadxacacdaacbxabxxxabdbxxxxxxadbxxxxacdaxdaadbdxbaxxxbxdxadxbxaxxcaxbxxbbcxdaaaadadabadbccddbbaddbadaaabacbbadxxxbabxcdadacbacccacbdaaacdbbdbadbdxdbbabbcbbdaabadbdbdbaacacdabdaxbdbaxxxxbxcabdxbdacacxddxdxadxabadxxcdaabbbdbcadbdbcbdbdbdabababadabxxacxxxcbbxxabxaxdaxadaadbaxxdxxxacdacadaxaxbbaddxbxxxxxxxxbccdxxaabdbdbxxacbabacabcbbdbaacadabdbbaadaabcdbababaxdxbbcddbxdxdacxxdaaxxdxacbbxxcxacbdaaxaxxbacxxbdxaxxbadbacxxxaadaaddxaaaaaxdaxbdbcaxxxxxcxxaaxcxxxxbabxxxxadacxxxdbdbadaaadaaabddacdbababcaabaaaadbaaadabbdbbabdbdbdbbaabdbbaxaxbbbdxdaxxxddxadxdbdxxdxxxxcbdbcbaaaaxxxcxxxadaxacdbdbabdbadabdbabacbabaabaadxxdxaxbaxbdacbacddabccbdadbabcxaxxdxadbbxxacxxxbaacxbxcxbaccdaaaaddbdacdabadbaxdabbacbcaaacaacbaabaacdacdxxacaabaaxxxxbbdxxbdacbadbdabbadababadbacbaacdaadacdbaxdxaaadxaxcxdaadxaxadxxxxxxxxbxbdabdbaadbaaadaaabdacddaaabcdbbabdbaacbaddbbdbadbxabxaxxddbxabxbxabaadabbacaaaadacdbdbbxxdbabdbaadbacddbdaaacbxxxaccaxxaxxbbdxxxdabbaxcxaaxbbxdxdxbdacxaxcdbdaaxbxxdaxcaaaaxaacxbaaxxaacxaxaaxxcbxxxxxxxaxxxbbacdbdbdabdadbcaaaaaaddbacdabdddbdbdbbdadbdddxxadxxxdxadaxxxxabaaaxaaabcbxxxcxdbaxxcxxabbdxcabaabaadaadbaxcxcbxxdaxacabcdbadbaaaadbabxbxaxdaaxcabxxaacxcxcdabbaaxxxxaaaaaxxxaxadbaxbaxxxbxaxbbcxaxaxaaxxxxaacdbacbaadbdabbcddbbbccdacbxacbaaaxaddbaabcxxxaaxxdxdxdbxdaadaxaaxxbdcbbbbabbdadbddbdaxbxddacdbaadbabbdabdaabddbdaaabddxxxabxbabaxdacxxcdaxbbacxaxxaaaxxdaaabbbxbdxdxdxbaadbaddaadacbdbdabbbbdxaxxxxaxxaaxxxbccaxbxaxxabxxbbbcbacaababcbbacdabcxxxacdxabaxbxxxbdxbxxaxxdxdabdbdbdabcadbabdadaaadbababcbacaadbdacdbbcbdbdacdacacaaacdaacaadaccbdbdabaabbacadaxbdaaaxbxdaadxdaaacbacaaaadbdbdadaaxxdaxaabdbadadadaacbdaadaaacxaxaadaxdxxbxxcxxadxabdaaxxcxxaxcdbaabxxaxbxxbxxccxcabadabcaaaddbaccaababxxcbxaacdbacacdadaaacbaaaaacbabxxxxaxdxdbcccdbdbcbabcbbdbbcadbbabaacdaaddabcadbacddbadaaacbdabbaxdxaxbddxdbdbxbdaacxcaxdxcbbaxdbxxxxbbabbccbxbbxadxabacdxbxxxxbdxbxadbxdxxbbbdaxaxbaxxxdaadxxxxacxaxxaxbxdxaxxbbadxaxxabxxcxxbbcaxdxbbdbdbdaaaadacbabacacdadacdaadadxbdadbdbaabdbaadaadaabdaabbabaaaaacbdbaabdbcbababdbdaaacbbacdbbabdaabbdaacaaadacxxaabxaxabdbbxxabbcacdbdbdbdbacadadadbbbdaaaaadaabcbddabbbcbbaxbxxcbxbxcbdacbbxadbxaaxcxadadxaaxxxxcxabxacaabbaabacaadbabdaabaxbbxxccaxcxbacbcxdadxcaadxaaxxaxxxacacxxcaaxaxcdbdxxxxbdacbdbaxaxbbxxcddxdacbcxbxxbxaxbcxaxaxaxdabbadxbxxxdabcaaxaxbcxadbcxxddbbaaaaadaacaacdbdacbacdaabaaaaababddadxxdbbaacbaaadaxxcadaxbadbbcbadbccdbaaaacbbaddbdaxxxxdbcxcbbxxcxaxdxdbdxabbxxbxaxdxxxbxcbaadbaaccacdadaaacdbdaabdabaxbaaxbxdxxbaaxabxaxcadbdacxxdbxxcbaxdxabdaaacbbdadabbdaadbbaacxdxdxccxaxbxdxbxxxaxacdxaxdbxaxabaaaxxdbxaadbbdxxbaadbxbcxaxxbbdbdbdxbabbbdacdbaaadaacddbccbcbbbaaaaxaaacxaxcbbdaxdaaaadbbccaccaaadaaaxxcaabcxaxxxaadbcaaxxaacaaabadacacbcbcabababacbbcbbaabdabbaxdacxxaxbdabaxaaxdxdadbdadbbdaadbbdaaccacdbdddaxaaxacxaaacdaacxxxxxxxaaacaxaaaxdbxaaxxxdxcbdxbaacabxaaaxcxddxxaabdxdxaccxaaxxcxxxaxbcbbxacbxdxaaxxbadxxaxaacdbaaxxbacabcabcbbdaadbdabaxcxxxdbaaxaxaacxaacxcaxaxdbabxdxdxxbabdbcxbdbxbbacacdbdbcbxbxxxxxbxdxdbadbbadadbaaccddbcaccaddabadbxdxaxxdbaadacdbaaacaaaaaaddacbbddaababcaddbbbacaxxaxaaadbadbddbdbdbccdaaxbaxxxxxabdbcxxxaadbxacaaacabacdabcbaabaaadabdbadadbaxcdxxdbxxbaxxaxcxdxxxcaxxaxxaxbaaxadbdabacdbdbdadbaaadbcbdbbacadbaababdbacbdbbabxabxaadxxdbabdxxxcdbbdxxaxxdbxbcdacbcdadbaacdbdaadabcacdbaaacddaababdxcbaxxaabxcbaxbaaxddaxxacbxxaxxbxaddbcbadbacbcbcabdaccaabdbdadaadbdadbbcaadabbaacabbaaacdbaacdbbadacaadaccdabcdabbbxxxcbxbxxdacxxxxdaaxcdxxcxxxaxccbxxxdxbaxdaxxbxxxaxaxbabaxdaaadbaacbdacacabadbdadxaxaacaxxxaxdxdxaaaxbxaxadxxxaaaxxdxacdxcxbbxabcxabbdbbxxdxdxxaxaxadxdaxxaxcccdxacxaxbdbcdbadbabdaaabcabacdbabdxadacdacdbdacdbddaacbaaxacdbcxaxdbxbxaxbxadxdaaaaadabdxxxabadbcbcbdacadaadabdbacaxdbcdxcadaabdbaddadaadbdbdbdacbdbbaaaaaxaaxdaaaxaabxbcbbaaabaaadadadbxabdxaxadbxxdbxxxxacbdbaaxdxabacdbabdbdbaaacdacdabdadaaaaacaaabaabcbbdbabbcacdbxxcdxxaxaxxbdadaaxacbxaaxbcadacdaabaaaacdacacbaaaaadbadacacdbacdabaaaadadadadbbaabaxaxbxaaxdbbdxaxddbxbaxbaxxdddxxbbaabxbbdxdbdbdaacbcddabccbbabababbdacbaxcxdaxbxaxcbxacxxabaaxxxaxabaaxxaxcddxdxaabadaacbbdacaabdaaabaadbacaadbbacxxaaadxbaaxbdbdxxbxdxxbxxxxxxxcaxddbdadbdaaadaacdbabaacabaaaadbaadabcxbaxxadaxxbbdxdddddxcxadbdabbabadaaadbaacaxababadabddbbdbaxbaxaxxbxbcaxaaxaaxdxxcacxxaxdxcaxbbxdbdadadadaabbaaaadbaaaadaaaabdaacabbdacdadacbdaxaacaxabbaaabdbaadbdbadaaxbaacbadbxaacaabdaxxacbdbaxxxbdaaacdadaabdbdadbacddabbaaaxxbdxcbcaaabxcadxxaxbaxaxbbxaaxdadxbxbxdxxdbxdacaabxbxbcbaacxdacdbcxbdaaxbbdaccbabxxxxdbxdbxabaxxcdaxxaacxxxaxadabadaxxabaxdbxxxcaabxaxxbdabxxaaxxabbadbbxabxxcddacdadadxcddbaxdxxxxbbxcdbdbacxdbbcxadaxacxxxabadbdaaacddadbdbbaaaccbdaabdbacbcdbaaaaacaabaacxaxbdbacaxxdxaxbxdbxdaxaxxbxaacxxadaaxbdaxxxabdbxxbdxbcaadbxcdbxxxxxdbxbxxxadacxaaccacdaabdbdbdaacacbbdaacaxbaaxxdxxxdbbdadbdbcababdbcbdaaadbaaaaccadadadbdbbbcdddacbcabcxbaxbxbxxcxbaxbdbbbdxaxxcxxbdxaxdacadbdbdaadaaadabaaacbbdbxbcxbxacaxxxdxadbaaxxcdxxxxaxxdacxbababxaaaxxxxbbdxxxxaxbdabxxbbaabdbddaaabdadbdacabdbaacdxxbbdddxbaxxxbbxxbaxccaxbaxxaxxxxbxcxxaaaaxxxbxccxxxxbxbdaxxxxxxbxbaxbxxadbaaaxaabcbdxcdxcxxxxacxxxaxbdbxadaadbacabbdbbbababcdaabdbdbxaxxdxxxacbdadbdabdbbadadaaacbaaacabdadbcbdbaadacbddbbbcxxaxcxbxxabxadxbadbxbbxxdxxxbbdbdxadbcaacbabaaaadacadbbdbaabdxxcdxaxdxbxcacaaacdabxcbxxaaxxbaxxdaxbdxaaxbxxcxxxaadacbxxaxxxaxbdaaxcdaxdaxxabddbxaaxdaxxacxacxxdxdabbaaaabaadbcadaxxxcdaxxdxxcxxdbaxxaaaabaxbacxxdxxaxxacdxdxxxaddabbdbdbdbdbdadabadxxbaaaabacdbdbadabadacbaaaabdbddbbddabaaaaadaaabbdaadacdaaaadxdbcaxbxxdxcbxbxdxxbxxxxbacaxacxxxacxaxdaaaxaxadaaxxabxabddaxddbacabbdbdbbaadbacbdxxadxadxxdxxxaadbbadaabaddaacadadadabdxaxxaxdadxxbdabdxxxxxaabdbbbbdacdabdbdbacdbbdbaxxdaaxbbxxbdxaabaaxacdbaxaxxxcxcdadadabdaadaabbacdbdbdadbacaacbadaacdaccdadaadaaadabbadddaxxabxaxaaaxabaabbadaabdbbdadaacbbccabadbdadbaadaddaabcaxxcxbaaxacaxxaxacxbxaabdaxdadbaaacadabacdbcaaaaaabcdbdbdbcdadadaabcdacaaacadacbdbxaxdaxaaacababaaadacacdbadadacaaaabbabcaaabaadbaaacdbcdacdbdacaaaaaaabbcdbddacdbaacdbadbdbabdbdbabdbaaaccbdbaaadddabdadaadxxxbxaxxcxxddbxcxdaabaxxaabxxxaxxxaadaxcdxbxaxcxxxxxxcdbdbadxxbdbxxbxbabaaxaxcbcxxxcxacdacbadadbabacbabbacdacxbacdabbaadbcbcabcdaaacbdbbadbacbabbdaaadbdbcdbaaaaabaccabdaadadadbacaaadbbdxadaadaaxxxxaaxxdbdbxxxaxxaacadadacdbacacdbbadbbabdaaaaacdacbabxbcdbdxaxddxdbxxxxxaxxbdxxbdbbxdbdaabaxbaxadaxdbadbaxaxxxxaaaaxxdbbxxaxxxcxaabaaxaxaaaxxdaxdabaadbxdabdbadddbdadxaxabdaacdbdadaaadadaacbdaacabacbaaacbdbdadaddaaaaaaacabdaaabbaacdbdaaaaabaxxaxxaaaadbacddaccdbacdaabbaaadaxxaxxcxaaxxdxbxaxxxadxaxaxxcdbcabdbddadbdbacadadadaaaaxxdbxaxxxdbcxxxaaxbabbdacbabacdaddbaadaxaadaxbxabaxacabxxbbxxxxxxxaadxxacbbaacaadbxxxbbacbxabdbadxxbdxcdbadaxbaxbxdadbbadbdbddaadaaaccbacdaaadbabaabbbxaadxcdaxaccbadadacaaaaadbaadaaaadabdaaaccadaacabxxaxxbxdbbxxbaadxxxxxxaccdbdxxxaxbxabaaxcbaacdaaacaacdacdabdaaaadacbadbacdaaccdaxaxaadababaxbabbabbaccdabcdaaddacxbxxaabbxaxxbxxxcadbdaxadadaaacdbabdbdabadbcxabcdxcbxcacxdbadaabdbbbacabcdadbaaaacadaadbdacdadacdaacaaxbaxxddbxxbcdxxbaxxacbbxbbxcbcdbxbxdxxxdxbxcxaxdxxbdxbaaxxdxabdbaabccbccaxabdaacxdaxxaxabddaxdxaxxdbacbcacxaxaabxxdxxxxxbabxxxbdaabadxdbadacdbbabbaaacccdaaaadxbaxaccdaabdxcxxaaxxbdxxacdbxaxbddacabdbbddaaaadaadabdbxbaaxxaaxbacdaaabcdacbbaaabadabacbdbadaabaabdbdaadabdbddaacbbbaaacbaaadadaaabaaabdbbcbaaxxxcxbxxaxxxbbxbaxxcaaxaxdxadaaadbxxaxccbxdxcxaxcaxxaxxxcdxxbbddaxbxxbaxadxaadbaxddabcxaadxaxxxdbadaaacaabddabbdbdaadadbdbbaadbadaadbbcadacaabbaadabbcdbaacdbxaaadaxxaacbadbdxaxxaxaxxabxacbxaxbababdaaaabbacdabdbcdxxxxaxaacbdaaabdababaabaddbcxaxdxxxxabacxbacxdaxxxxaxxbxbxcbxabbbbadbdabaaaaabadbabaacddaaxxcadbxaxdxadxaccbxabxbbxaxaabxcxaxaxxdbabaaabcbadbacadaaabaaxdxxxxdbdbaxbxcaaxaaxdxbxdaacbxxaxxacbbddaaxdaaxxcxxaxdxdxcxxaccbadbaaaaxbaxaxxxadbxdaaabadaxcaxadbcxabxcxxxxcbdxadbxxcxaxabacbxdaxbabbxabdabxaxabdxccxxxaxaacdxxabdadaxxbxcbxxbxbcdxaxbxcdaadbadbbcbcdddabaaabacabxxbxaadaaaaacadbbddbdbcddbaaaaabdbdaaxxbaadadbdabdabbdacdadxaaxccxdxxxacaxxbxdcaacdacdadadbabdadacadabdaaxaxxbbxxabxxcbxdacxbxxbxdbadaxcbdaaaxbcxaxdbdaaababdbaacdaaaacccddaxccdabdaabbababbdbabdbadbabdaaaadaadaadbadadbbaacaabdbadacaaadxbaxbxdddxdxabxaxbaxddxbbxxbaxaaaaaaababxbxdxaaxdxaadxadbxxxbbaxbaxdxaadbadaadaadabacdabdabxbabxadaxaxcxaxbxxbcdaaxaxbcaaaadacbbacbdaaacaadbacxcbxbxabxbdbdxaaaxxcdabxabxaxaxacaxadxdbaaadaxxxcxxxbxxaxbbcaxaabxxaxdbcaxxadxxxdxdacaxabxxbxxxxbbbxbabxbaxxxxdaxabxbaxdaacxcacabbbaadacbddadbdabaacaadbaadbdaabacbdabbdaacdxaxxadbaaxxaxabbadbdxabxaadaxxxxxaacaxxxxdaaaaxbbxxdadxxaxaddabxdxbxdbdxxaxxaxdxxxaxdbxxdbdbdxxcxxxdxxxdxaabaaadadaabbabdabdbdacbddbcbadbdabdxxbxxxxaxxcdbxbxxaadaacdaxdxxacxbabxaxabbaabxxcacbaaxcacxxaxxaxdbxcaaaxxaxabxacbacabdaaaaccdaaaaabddaaabacacxcdbaaxaxaaaaxababcdaacaccddababdacadbdxxxxcxabadaxbxcbbdbbaabaacbaaaacdbcbbaacaacbadbacadddaaxdbbaxxxcbacbabbddaadadabbdaaacbxxaaxaxabcdbaacbaaaabaaababaabbadaacxxaadxxcxaaaxbxdbxdaaadadbbcdacbaaabdbaddaddbdxaaaxbacxxdxdxbabxxcxxaaaabaadbdaxacxxxxxaxacxbaxdaxbcxbcadbdabdaadadadaacbdacbdabdbacdaaacbdbadbaabcacdadaadbcdabacaaacadbbxxaabddxaacdxxabxxaxaacdxdbdxxxxxaxacbacxbaxaxxxaabdbbdaxdxabxcxxadxxxdxxaaxxaxacxaxbaxxaaxbbxaxbbbaaxdbaaxbxadxacdbdddaabdabbdacabbdbdxbbcaaxxbaaacaaaadaaaadaadxbdxaacxddabcxxbdaaxbxaadbacxxxaaxbxaaxcccxaxxbbdbxxxbxxadxdxaxxxdxadxbaxacbdxbdaccbxxabbbaaaaaaaadabdaaadacbdadacabaaaabadbadabccaacacdbbddadabacabbcbaacdabbdaabddaacxbdacxxaacxaaxxcdbaaxxbxadxaxdxxxaadbcaaadaabbaadbacbabbdxbaadadxabxxxxbadbdxbdxbxaabxxaxcxbxdaxabdaxxdxdbaadbabaddaabdaccbaabcabccdbbdaacbcxxxcxabxaddxxbbxxaxabdbxdxdbcbcaxxxxbcdacbaaacbaaacabdbaadaaxxdxaxaxdxaxxxcdbadaxaaaxxxaxxaadabbbbxxaaxxbaaaxdaaxxdbdxxabaacxaaaaacdaxaaacaddabcbbdadadbdaxxxdxdxcbabxxxaaxacxacaaxxxbdaacacxadxaabbbaabbababbaaccxbxbxaaaxcxxacaabbacdaabdabdaacbcaaaaadbadbabaaacbbacacdbcdaaaabbaddaadbabaaadbdxbadbdababbaaccdaabadacxcbbcdaacbdbdbaabbaxxxabcbdbbcbdddbcaccaaacddaacaacbxdxdadaabdaaddacdbdbadbxxaaxdxbaaaabadadbbbaabcdbdadbacbbdaaaaxacbbabdbdadadadaccaaxxxxxaxbaabdadaacbbabddaacdabbaaaxdxdbxaxdaxabdacxxbdxbcaxbxxcdxxxxaxdxaaaaaxaxxxxaadbdxxxbxxcbacxxbdbxbxbxaaaxxxdaaxaxxdaaaacbaaxxxaxadxcxxdbbaacbaacdaaaadaccdacxadxxbaaaacaxaxaaaaaadabdaxbxdbdbacaxadaabcaddabcabbaadacbdbxxxdbaxxxbxbbdxbdxbddbaccddbabaaacbaaaaaabacdaadabbaadacabaaacaxacxaxxadaaxbxdxxxdxadaxxcacaxxbxbxabadbddabaacddaacbdaaaaadbdaaxaxxxxxcdbbbxxcbdaxxxdadxaxbbdaacxbddbaxaxxdxxaacaxccddbxabccxxxaaxbbdxdxdaadaaacxxxaaxxaaaaddbcdadaccbacbabdbaaaaacaabdabdbbababdbaaadaaccdaaacdbcdadacdabbdacabaxdxdaxxxxabxxxacbxbxadaacdaacbacdabaaaaabdbaabaaadabbbabbdbdbbcaadadbabacxxaaxdaaxaxaxdbxaaaxaadababbdadbaaacbdbabbaacbdxdxxxxdxxbaxcxabxbabaxaabxbxaaaaxaaxdbxxaxcdabxxadxaxxdxabadaxxbacxxxxxaaaxxaabcbaaaabbddacdbdbcbaaaaaacxadbadaddacdaccadbaacbbadabxxxxbxxcxxcbdaabbacbadaaaaaabdbadaaabdabbaaddbxaadbaaaaaadbbabbabccxxdaxcaxbaaacdxaxxxadaadxxadxcdbxxxxxxxxbdbaxaxxxcadaaabcbdacbdbddbabaaaacdbdbbacaacdbacabaadbxbbaaaxxdaxcxaaaxxxaxxbaaxbxaxdaxdabxdbaaacbdbaxxbcbxdaxxbadaxxbabcxbaxdbxaxxxdxxacdaadxcaxbcxaxxxxbdxxxxcxxbdbdacdxxxxdxabdacxaxdbdxadbbxxxabxcbaxxadbdxddxxaxbaxxcxaxxxxabaxxbdbbbacbdbacdddaabbdbcdbaxaaabaxxbababacabacbbdbdbacdaccbccxdxcxxcxxxaccdaxdbabbddbaabbbabbdbbaabxaabbxaxxcxaaxxacbbdbbcadbadbabdaabcbcdadaaaccccabcaaaacbdacdabbdadadaadbaaaaabaaaaxaadxxbaxbbaxxxxxacbaaxbdxdacddbadbdbbacdbdbaadaaacbdcaxaxxxcaacxaadaccdbdaacbdbabadbdadadbaacbaxdxxaxdxxdaxxxaaxbdxbbdxcxxabxbaabbacaaabxxxxaddaxxxbxadxcacbaabcaadadbdabcadaaxdxxxdxaddbxxxxaaxdxxdabacaaabdbbbadbdaadbadbbaabacbdaddadbaaaacxxadbxaxacdxbxaaxbxbbxxdbcxbbaabdabdaccadbabadbcbaaacdaaxxbdabdadbdaaadbaadaaacdbaabaddaxaxbaadxxccdbxxxxabaxaaaaaaxdxxaabcaxxxxxdxxbbxxxbxacdxxxdabadabbdadbbcaddbdxxxxadbxxdxbaaxaxbaabdxbbdbadaadaabbbdbbdbbacbxdxxxbxxxdbdxbxaaaaxxaxxxacdaaxcdxaaaadaabxxdaaxxacaxcadbxdabaxdxacxxccdaccccbdadbaabbdabcaxaxbdabbdaaacbdadadaacaaaccaaxbxabdxxxxxxbdaxaaacxaxdxcxxxxbdacbbaacbabcbbbbadbaacacdbdaccdabdbaaacdaacacdbdaabacbacadadbbaabbacadbbdacacabdaaacdadbdadacbabaaabaxcaaaaaxxaacdxaddxxxdadbaxxxdbxxbcddaacabcbdaabbcbadaxxxxaxxxdaabbacdbdaaaacbaabdaacbaaxxbbdabacdadbaccdabdbbdabdbbacabbbdabdadabbaccaaaadbbbdaacbxxadbcddacdadbaaaadbdaadbaabbadbdacaxcbcbbxadaddbaaacbcdaaaacddabaabdbdbdbaxxbcxadbxaxdaabdxbdbbxxdbacaadbdbacdbabbabbbaaacbcaacaadbaaacbdbxxxxabaacaxxxbdxxbbaacxaxxdxxcxxdxdxdabxxcdaacbdxxxcdxdxaxdabxaaxacdxdaaxxdbabaxxxdadabdbcacacadaaacadabdbdxdxbdbxbadacxxaxbcxxaxacxcdbxbdaxdbbxcacdaxxdxacbaxxaxxacxaxxaxdxxaxxaxabxxxxbxacxbxbxdbxaabxaabdbxdaaxbadbacaaabdadbaaaabcbxxxaxxxdxxxbdaaabdxbdxaxcxbcadbdacdaaaaacadacaaadbaaacdbaxdbadacbabdbdadbadaababdddbdacbbdbaaabadbdddadbacabaaadacbaadaxdxbaxxxadxxxababdxdbabdbxbxxabxdaaccadaadxadaxxxxbaxxxxaddbcdaacdbdbbbaaaadabbaccdxbdxxxabdadaxbadxxbdbbxcxbbxaxxxxabcbababdaaadacdaaadxaxbdaacbxxddaxxdbxxxadaacbaadacbbdabdacdbcbadbaaxxxadxxaaadxdaxacxaaxxbaaadaxabdxaadxbadbcaaadxdxaacdaabbddbacbddbdaabcaxaxxxxxxacdbdaddacdddadacbbdaaabdaacddacbdadbcdbdaacbxbbddabbxxxbdxbbxaxadxdaxcxaxbbdbxbabxxxxbcacaababxdaaxxbxbdxdbbxxaaxbbdaxxxbaaxbxxcbdbxabcxxcaxcxxxdaxxxabxaxcxdaxbxaxaxxcdbdacdxxxxxbbcxaxbaabbdbbdbaadddaaabdbacbabcadbdaabaadabxadbcdaccacbdaddaacaacaaabaccdxxxxaxxacbdbxdaxccxbdabbaaacdadaaacdbbabadacbdxbdxdaacxdaabaacbdacaxdaaxadadbxxxxdxaxbddbbaaaabdbacdbcdaxxbxcacdbxacccbdbbaadadbddbbdbadadbcbbacdbbacdbdaacabcacdbacbbadbacbaaadaxbxxxbxbaaxdxdxacbbxxddaaxcxbdaaxaxaxddbdabaxacdabacdaabdadbacabbbdaxdxaxdxxbdbaxxcxaxaaxxdacdbaaabbadbbaaaddacbabaaxxdbaxacxaaxaxaaabbddxdbxaaxxaacbcbbaabxaxaxaxbxbxdbaxaxaabdbaadacadaddaaccdaaadddbaadxacxbbdaaxxbadbxaxdxcdabxbxacxxxdxbxxbxxxbadbbcadacdbadaaadbacbdxxdaxxaaaaxbdbxadxbcxbbaxdababcbddbacdbdaadaaacaddabaacdbadabcacaacaadbdbacaabxbxxxxcdadbabaaaaadbcbaaaababxaxbaxacxbaxxxdbxxadbxbxdabdxxbadacbdbdbadbaadaabadxcbdxacaadbdabbcbaaadaabbadbdddabdabdxacxaxxxbxxcxaxdxdbcbaxabdbadaacabacbacdbadbcdaaacbxaaxcaaaxxadababxxxabxaabcaxxxxadxabdadbabbbccdbacdaaacbddadbacacaadbacaacbaxacxbbdacbaaaadabbdbdbaacddabaabdacdadadadbdbadadaxxcbbaadbxdxxaxxbcdabdadbcbbaaaaaacaacbaadaaacbaaaadaabacaaacxxaxdxbxxabbxadbaadxxxxdabaxaxxadaxcxbaadxaaxdbbacxxdxacdabaccdbabaaaaacbabaaaacxaacbxbxcaaxadxbdxaxxaxaxabdxacdabxxbaaaxxxaxxadxcdbcdbdaxdbdaaaaacbacaaadaccdbxxbxxxdbdxxaacbxxaxaxdaxbxadxbxbxaxxxxxxbaxxadxxdxdxxdxxbaxcdxxaxxcxxxxbabaacbbabddbadbcadbabcbxbxbxdaxxxxbaxxadxbxdaaaaadacadacddabcdabdbdabdbaaabdaabcaabdbbddbabdbbbdadxbabadxcacbbdaabbcbaccbdaaadacbaxadbccxcdaxbbaxdbbaxxxxcacabbdbdaadbdababaaadxxxdxcaaacabaaaacaabcabbabdbbacbabbcbaaaddbdbbbaaacbdbdbabbacbdaxdaxbxdaadxxaxxxxbdaacddbxdbdxdxbxdxdbcbxacxxxdbdbbcadaaaaaabbdabdbcacbdabdaaacaxdxbdaacaxxdaaccxcbxcadacdadaacaacadadaacaccbbdbdbaacaaxdxxaxxxxaxxaxdbcxabacbdaaaabdaacaadbbxcbxbxxcdxxxdxdxcxbaxaxdxxxxxxdaacxxbaaxxbxbbdxxcacxxaadabaaaxadacxbbxbxbabacxcxaaxxbdxxxbaacaacccbcabdbdbbdbbbxxacxxxxdxbxxxdbxbxabxadaxccxbxxdbdxxaaabaaabacdacbdbbdxxbxaxcxxbxxxxbdbaxadaxdxxbaxxdbxaaabadaaadadbddabddbddadbdbdbabaadbbadbcaabacaaaaacxaaxabacbaabxxxxdxxaxaaaxxaaabbxxdacxxxxxxaxdbxabcbxxbxxxcxbdabbdbacbadbbbcbaacdaaaacdxxxxxaxaaxxxaaxdxxcdaaabbbabacdaddbaadbddxcbxacbxbxaxadxxdbaxxbaxbdbbcddbdbdabcacbddbdbacadabbbbdacabdacdbaaaaaaaddadabaabcacdaabcbadbdacbdbdaaacbacbbaadacbdabacdbbbdxdabcbxxaxxxxabadbbxxxxadxdaxaddxaadacdbdadacbdaddaaaaabdaadxbaxdcaadbccbacdbbdacdaaaaaxaxxaaabadbxcbaacaabadbbacaacdaddbdbdbdacbadacbdbabadbdbaddbdbxxcbxxcabaaabxxxxdxaaadbxxbaxxdbdaxdxxdxxabxxdacdbccdbdaacbacacdaccxxdxxxxxxdbdbacbcaababaacdbaabdadbaadbdbaadabbacbaacbdbcddabdabcdbabadxdxbbxcxbxdbadxaxxdbxxxxbdxdaxaxadbaaxxaxcadxxxxcdxbaadbxxxxadxdadxdbaxxbxaxxbaaaxdaaxaacbacdabdbaaccbdbababbbdbadaabdaxxaxxabxxxxxdxxcaxxdbaxabxxbxxabaxxbabaaxbcdbbdbxabaxbaxaxxaaaacxxabacabaabdbbccacxcxaaxaxdxaxxxbdaxbacdaaxaxbbadxxabxdaxbcbacbcxacxabdxxbxbdabxbxxaaaaccdxcxxdbcxccxxaaxdbdxxbxaaabxdabxbaabbcbbaaabaaaadabcbdabbcdacbaaaadadaccdaaadbdbbdbcaxaccdbdaacaadabdbaabaaacaaccxxacadaxxbxaxbaxxxxxbaabxaxbdaxabbaxacxcxxaaxbxacdbdaacdbdbaaabbdbbdadbbdacdbdaacadabaadaacdacadadabaacadaaaaabdaadadbdbbaadadbdbbbaababdabdbxxbxxxbacbaaaxxdaxxbxbaxbabaaabaxddbdxbabcxxaxdxxaxaxxxaxccaxbxxdbxaadbdxaadxxcdbaxaxbxdxdxaxbdxaxaadxxxbaxxxxbxxadbaxcaxbxxxxacaadaxxdbaxbxbxxaadxbdbxcdxxaacxdaxbbcdabdabacdacdaaacbdaaxbaaaaxaxxaxxbbddacxdxbdxabxxaxxdxdbbdbdbaadbaabdacdbaacbbcaadbcxaxbaabdbccbdaaacbacadbaxaddbaccadaaaababcadbaaxxcxacxxacdbadbaccabaddbcdaxxabaxxcdxxbxxabbdaadaabababcaaacacdbbaadabacadadxadxaaxbaaaxxcaxcxxxxxxbxxdadadacdbacadbadabcaabxxcbaxxxxadxaxxbxdxaaddacbaabaaaacdabcbdacdaacbdaaabbbabdxxxdxacxacaadbabxacdaxxxxaxddaaxadbxabxcdxxxaxdxaxcdxbxadxxbdbabcaabbccdxxadbxdacxxxxaadxaaxxxaadbxxdacxadxcxaxxaadxbadxaaaxadbxbbcxcdxdbxaccxxdacbbadabcdacdbcbdbdaadabddaacdbbxdbbcbadadxxaadadxaxbddxaxbbbxxxdxbxdxxdxcbxxbxcbxabxxxacdbaacdbxbxcxaddxdbaxcbaaacbbcxxdxxxxxdacdbdbacdaaaacbcdadaadbddbbabxxxxaaaaaadbabacbdbdbdadaaxxaadaadxdaxddaaadacxxcbacxdbxxdaxaaxxadxdbdadbdxaaaaxdxaaaxaacddxbxxxbxxadacbbadbaaaccbaddaacdacaadbddbxxdbabxdxcxacbdxadxcabcbaxbbaaxaadxdaxacbxxcxxdadaxxbxaxxcbxdxdxxaaadbxbxdxdabxxcxxxxbcxbaabbdxcbxaxbabdbbcdaabddaabadabadaaxabxxaxxxaaxaxxbbbaxaxxbxxxdxdaxacbbxxaxxabadbbxcdbaxxbcxdxbadxacaxddbxdxacxaxxaxbadaacdbaaadbaadbddabadddbdbcaxaaadaabaaacaadbccdbcaxxaxxbdaaadabaabccbaabcaaaadxcbaababababbdaabdbcbdbaaccdbbaacadacbadaaadadbdacbxaacbdbxbdaacaxcxxxxxbcbabxbxaaxaaxbxadxbbxxbaacdxaxabxbcaxxxabxxdxxxacxdaxxcbxdbxxdbxbdxxcaacdbabbdbdbadbabdaacacdaadadacdbdxaxabxbxccxaaxdbxxdadbaabdaabbadaaababbdaaacbcxxxdbdxaxcabcdbdacbaadacacaaacdaaabbddbdbcbdbaaaadaddbacdxxaacaxadadbabcaxabxaxabbxbbbabdaadadacbdaaababacbacdbbbdadbdacbdbadbcbdbadabdaaaacdbddaxaaxxxaxxbcdxbxxbcxacxxbdxaccaacbdbcxaxxaabbbxadbdxcxdaaxaxxcxbaaaabxxbdaxxabbxabxbxbxaaaaaxacxxacaxdxbdadxaxxaadbbcdbacbcbdbcddaaaaxabaacxddadxxxxdxxbdbacxabxxxbxdxaxxcxbdxxdaxxacxxxxcxabxxbxaxadxaacbxxaxdaaaaabxxxadaxbxxdaxxxxaaaxaxaaxcxxbdaabxadaacxxdaccdaabdaacdbbdabddacbdadbabcdaadaaaxaacxxxxddaxaxxbadxacbbaadbacbaacbacaaxaxxbaaxabdadxaxxcxaaxbcbbxcdaaxxxxxadxxcxaaxbcaaadaaaabaaaaadadacdbdbdbabdxxxxxxacxxbabxbxdbdbadbcaddbabcdaaadbdaxxxaxxxxbdxxcdxxdaabcbdadbacbacbaaabdbdbdbaxxxaxxdbxacaddacxbbxxdbxxaxbdxdxbxxcaxxaxxaxxbabdbabacddbacdaaacaaacabbdbdbaaadbdadbaaaaabaaaadbaaababdacacbabdbbaabaaabbdbbacbbdbadacdbaabaaaabbabaaabababdbadbbcdacbadbdbadbaadaccdbbdbadbadbcabbdxaxxxxxaxaaxxxdadbacdaabbdbdbcbdabcxaxaabaxxccbdbacdxxxddbbaaabadbbbcbbabaaddbabdddbaxbxxaxxcbdbdxxxxdaxxaxxbbdxxxaxaaxbcdxaxxxxcxxbxaadaadddadacaadbbcbbdbdbddbdxcxaaxxxbxaabaxxbxaxbxaabaxaxbcabaxaacdbcdaaadaadbbacaaadbaacabaaaxcxxaaxxbxxbxdxdxbaaabddbadaxxcxxaxbadbdaababbadbbdbadaxxaxaxxdxxdbxadbdadbcbacaababdbcbacaadaabdbddbdaaacaacbbacaaadbadbaacbacdadbxbxxaxxabdxacbbxxbaxxaaacdacdaaccdbcaadaaacdadbaddaaxbxxaaxdxxcaadadbxaadaaaacbabccddadaacdxxxaxxaxaxxdxbaabdabdabccbdaabaacadaadaaxxaaxbdxxxdbxaxaaxxxaxxxcddxxcdxddxxxxxcdxxbxcdbbcadabcxddxcaxabxcbdxaxcbadbxbdacbaddaaacdaaaaacabdbabxxdxaxaxxbxadacababcaabadacbabaabaaacbaadadbccbadaaaadbbxabxxdxxaxadxaxbdacadbaadbbddaacbdaaaddadaadaabbdaaaadacabaababaaaddabbaadadacbaabdabdbdbaabbxaxaxacxxbaabdaxdaxxxxbbxxcxaxdabbacbabbaabbaababdbdbdacbaxbaabbxdxaxadbxdxaaxxxdbadbbdbxxbadbadbaccbdxabdbxaxxcdaxaabddxxbxcbxxxdaxxcxxxxxxdbxbadbxbaxxxxacdbaacabdacdaaabdaadbddddbdxxdbcxdaxdabxcxxxxaccbaxacxxxxxadbbbdabaaacabdacacacacadxacaxcbxdxxbacbxadxaaxxbxdacxxxddxaxaacdxaxaxxcaaabxxxdxxdaxadaxxadxcxaxcxxaxaacbxbaaxbdaxadxbxaabcaxcaxaxdbaxdxxdbxaaaxxcdxdbdbxaacddabbabbxaaxxaacdaaxdbxaaxdaxcbaxbxxxcaaaxaxadxacxbxdbxxbxxacabbadaxbxaaaaxadabcbdbdaaadaadacdabcbdbabacacxxxxcxdbxaadbaababadaaadbaabacdbcdadbdbaacbadddacbadadadabbdbadbaaacbbabxdbxxbdxcbaaxbdaxxxaacbaaacbacxbacadbxdxcaaaacacdbdaacabacadaaaadbdbacdacadbdxxdxxadbaxaaaaacdaaaaacbbadacadaabaacdaaaacddabaabdbcaabadddbbxdxaaadbdbcdaabaacdbabaadbdaadadaadaaabadaaaadababaaaaacaadbdbababdaaaadbadcacbaxxxdbdacbbdaacbdadaaddbbaxxcxacdadbdaaaaacccaadaabadadbbxaaaabdxdadaaadadbdaadbacdaaaxaxbxbdadbdxxbdxxxxdacaaacdbdbcbcdbdbadaacbaadbdbdaacaaaaaadacababdadddacaacbaaaabdacdadadbabbbddaaddaaaaaaaxxxdbxbaxcbaxxaaaxaxxbxcaaxxxcdaxbxdxdxaxxbxcbbaadacxxdaxxxxbxxcadxbdxxxbdaxxxdbxbabxbdaaaaxxaxxxaxxbaxaxxbcdbadacdbbxxxxdbbaaxxxbdxxbxabdbxacadaaacdbadaabacaaaddacccaadbccbabbacaaadaaacdaaaaacdadbxaxxabxxxcdaxxaaaaaxxdbdaacabadaadabbaadacbbaxxbxabxadaadbxxacbxabxxaxcdadaadacdxxaaxabdbbaaaaacbbddbbbaabadacdadbaaabdaacdacdxxadxxxaxaaxaaaxcxxcdxxaxxcxxaxdxaxxbadbacdbacacaaacabbdxaxxbdxaaxaacxaaaxbdbabbabbdddbadbdaabadaaxacaxaxacxxbxbabxabxxbbxbadbxxcdxxbaabcddaxcdaxxdaxaxxaxcaacaaabadaxbxxbxxcaabadacbbdbaacdacdbbaaaaxxbdbxcdacbxacdxccxbxxaaaxbacdxxbbacdaxacxxbaxbxbdacbxxxxxcxaxcbdbaacbdaadadacbbaaabdaabbdacdbadaxdbaabxxaadxdxaaadbdxxcxbxdxxaxbddxxxxxxbdxxabbdxxdbcdaxabaadaxxxbbxdaxaxxaxxbbxxdxxdaxxxadbxbadaabdbadaadbbccdacdaaaabadbaaaabdbadbdadbdabdacccbdbaddbbacaabaaaxbxxxxxdbdbxabxbxcxxbdbxbaaxxadadaaadbaacbababaacddbdbdaadbacaacaacdaxbaxxadaxxbcxxaaxdabxbxxadbdxxbxbdbbxdxaxacbbcabacdxxababxbcbaxdadbxbbdaaaadabdbaaaxcddxaxxaaxdbddbddadabdabbbdbaccadaaaabbacdxaxadacxxxxabdxaxdbadxbacxaxcadbdxxxbxaxxxxbxadxxacxxcxxxxbxxcabxddbcxaxcbbbxdxxxbdxdaxxcdadxdacaxbbxxbxxabxdaabbaabbcadbdbddbacbdacxdbbbaadbaadbccdacdacadbdacbxxaxbxabxdaaxdaabaabbbbdbabbdadaabbcdddxdaxcdaxbadaddacaacbaacaabxddacbxxaxxxaxcxxdacacdbdaxaacxxaxxdbbxcdabxxxxxxadxaxaxxdaacxxcxdxxxxcdbxxaxdxaxxabbddaacdabcbacbdacbbcbxxxxabxbxbxxaacdxaaaaxbddaddbaabaabbbadaacacdabaacxdxaxbxaxxxxxbabbbxxxaadadbxaaaddbaabaadaacdbdaaxdxbcdbacccadbcccabdabdbaccaaaababaadbdbaaacaaaxcxdxaxaxaadaxdxxxxxaxxxxxbdacbdacbadacbacadbaxacxaaadbcdxbdxaxxdaxxxacxbcxxbababxxcxacbcbbdacbbdacaadbadbdaaabadaacdacbdddaacaaaabaacaccbaabdaaaxaaaabbadbababcdaaaaaabdbaxxaxaabaxcbxxaacxxdxaxxxdbddabdaacdadbbbdxxbcbaxxxaxcxaadbxadbaaaadxcdxaabdxxdaabaxbdxbxaxaacadadbbbdbcababdbacdaacaaaadabaaaxxababxxxxxbxxbdbbxaxxdabxxbaaxxxdadbdadbacaxaabaaxxbbxdxxaxbxaabxxxxbaxxxxaabxxxabxdbaadaadbdadaccbdabadxdbcbcaaxxxxbxaxxbacxaxaxxdxacbxxxccdxaxabxaabxbbcaaxabxbabxbxdbxxdxaxxxddbaxdxdxdbbcaddacabdbaaacacbacabadaabccbdxcbaaaccabdbdbbdbbbabdxxaxxaaddaaabaxaxbxxbaxxaaabaaaxaxxdbdxadabxadxbxaxxaxxabdabdabaabadaaadbdaacaacacabcxxxaxxabbdadabababbbbdaaaacaaxaxxbaxacxxxabaxxadbcbdaacdbaacdadaaabadxacxxxaxxbbccdabbdaadadbaaacbbdadbcbbaxbdbbaaadaaadbacdaaxxabaaaxdxxxaxbbaabxabaxbaaxxxbdacbdacaadaddbadbdbbbacbdabcabdadbdbabadbdaxbbxaxxxbaxaxadxxcdaabxxaxbxxaxxxacdaxaxxdbdbdaadbdbaaacdadacccbacaxxxcdxaaacccdacdababdacbbababbaadxbxaaabacabbcbdbcdaaaadabxdxccxdaxbcdaacdaababbdacdaaadacdxxaxaaaxxbdadbdxxbdxaaxbxaaxbxdxaxxxcacdxcbxxxxxxdadbaabdbbdacdbbadbadbbdbabbdxabaabaaaaxddxxbxaxbxcdabaadxxdbxcxbdaxxacbdxbbdxxxdabxdxaxxacbcxcdaaxbbxxdaxxaxdxacbabaaababacdadbdacbddacaadaabaadbcxaaadaxbbbddbbxdxdbaaxaxdxcbdbxxxabbxaaaaadadacdadbdbdbdbddaaaaabbdbbaaabaadbdbacdaabdadabadbaaaaabdaxxbabxbxxxxadxdbaxabxdxxxxxxacabbbxxxxxdaxxaxxxxxbadxxdaaxdbbbaaaxxaxadxxxdxdbbdxxxxbaacbxbxbdxdxxxbdbabxbbxxbxdaaacdbaacbdadacbbbbdaabcadacbbadaccbadacaaxacxxccadxdaacbdbbaaacdacccbcdabbabaccbabdddbdbaaccdbdxxxxacxaccbbaaaaaabacaddbcdabacadbdxcaxxdbddbaacadbbaxbxdaabaxxadaxdabbaxxdbaacacbdabdacxbxaaaacxaacaaadbadbacbdbdbbdbbadacdadbabaaacaaaabddbadbdacdbabddbbdbaaaaacdbaaadaadbaddabccbdaaadaabdbaaadxxadxxabaxacddxxbxaxaxxxxaxxdxbdacxcbdaadbaxxxadaxadaacdxxxbxbaxaadbxxxxdbdaabbacaabdaaaaadbdbbadbcbbbdxaxaaaddaxbdxxxadadabdxxxxbaxbaabxxbcxaxabbaaxdadxaxdxxadbxxbadaxaxdxdxcxbbddaxxbxbxbxxaaxaccbbxbbdxxxxacaxxdaaxaxxaxaaxaxdaxxbdbbcacdbabdbdbdbcaabbacdbacabdabddbbadacddaabaacadacaaaacbbdadbdbbacdbdbddabbaaacaacbdbcdbdadxdacxacxxaadxxxxadbabadbbacdaabacbaaabbdadaddbbcadaaacdbcaaddaacabbbxxxbxxadabbdxbxxdbbadbcababaccadbabaabaxxaddadxdbxxxbdaxaaaacddbacbxbxxaxxxbaaaaadaacdababcdabdbaaxcxxxababdxxadaxcdbcddbaacaaadadabadbbabaaaaadacadaxxbcxdaxxxxxxaaxaccbaxaaaxaxxadxxaxdxaxxadabaxxbxbdacdaxdxxaxxxaxdacbcdxbaxacxxbxaxacddabdaadbdaadaaaaaddaaaadbaacbadabbdacbdbcbbaadbabccbacadadbdbabacbdbbaccbababdxaxaxbacdxdxaxaaxabdaxxxaaadacxbxxaaaxbaacadaaabaadaaadbacbbaadbacdbddbaccababadbacxxcdaaaadaccadaaccbdbdbdbcbdbdaadbdaaaxaacbadxaxxdaacabaaaxbxxaaacdbbaxdaaacxxxbxxdabbxdaaxacxdadbdaxxcxxdxxxbxaadbxxaabaxxxcxxcdaxxbxxbaaxddxdbacaaaabxdbxaxaabdaadxxaxaaxxxxcdabbaccdacdabdbcdbdbaaxcdxcdbaaadbababcbaabbbbbdaccaabxxcbbdxbxaxcbxxabcbcbdbdbaadbdabaabdadaaaabbaacdbdbabaabcbddbabbdacdbaadxbdxdaxbbbaccdacddadadbadaaxaxxcbdadxbbxxadaaxdbbaaddbbaacbaacabadabbxcxdxbbxxabxbxbabaacdadabaabcacdxdbxcdxaaadbbabcbdaabbdaaadaadbdaabaxaadbcxaxdbacaxxxcxabdaxxxbxaxxdbcxxbbbxxbaxxbxaxaxbxcxxaxdbddxaabdbcaaaabaadadacbbaaadbacaabdxxxbxbxxxdxdaaxxxdbxbdbdxxcabbbxaaaaaaaabaaaacabaadaabadabbxxadbadbadaaaaabcbdaadaadbbbdaadaabaaacdbcadbxxdbxbxadxxdbaxaxaxxaxdadbdxcxadbaxxaxaxbxcxdxxxbabdacadbddacaccaabdaddaxcddxbccdxxxxxabxxxxaabcdxbbxdxxxxxaaxabaaxbadbabxddbxadxxaaxadxacxaxabdacdadbacbaacdabcbddbadbdacbbabxxxdbdbdaacabdbdbdbcbaccdbbccbcbbcdbcacddbccbbabaacbaaacbaabadaabacbcabaadadbaabbabxbaxdbadxxaaxadaxabdbaxxaacxxacaxxxxbxxdaxxaxxcxxxaaxcxacbdxaxxcxbabacdaaxxbaxxxabxxxbaacxxabxaxxbxacxxxabdacdbacbdxacbdabacxxxdxxbxbbxxbxxbaxdaxbdabaaaacdabaaabaccxbxadadaaaxxaaxbxxxaxbxaadbaxacadbaaccbdacddaacdabxbaaxxdaaacbdaadaaaxbxcxcabaaaaacdaaaaxaaacdbbaacxbaxdaadabdxacdbdaxbbabbaaacacbadbaabaaccxxbbxxaacaxxbadaxxbbacdaacbacabbdbbdbabcaadbabbaaadbacdabbdbdaaabdbdaxaxxdaabbacbacaxxxbxdbxdaaxxbdxdadabdaddacdabddabdabdbacdadaacabdxxbdaxabxdaaaabadadaaaaabdaaaadxcbxadabcaaacaaadbdaaaabaabadbdbbaacbabaxacdxccdddxxxdbxxdacxaabdaxbdxxadabaacdbdacbbcddbcbbdaxaxaaxxxdxxxdaxxbacxxxabdaaacbcdadaabbdbdbdadbbacbadbaxxxxaaxxacxdacxaxxxxxdbxbcxxbdbdxbxdadxaaaaddaaabdadbadadbbddbcbbbacxdxxxxdbbdxcbxaacxadxxxxxaaxxxxacxxxababbcxxxxxbxaxabbaabaabbadbdbcabaaacadabaacbdaacbddabaacbdbaaaacdbbddbbaabdacaabaabdacaaaaxcaxabxxbaxacxabdxdxdbdaaaaacbdaabadabbdbaaadbbdxcbxcdaxxadaxabxaxbaxbxbxcacaxcxdxcxxbcabdbaaaaaaacaacabdabaaaacbcacdadbdabadbdxxaxxxdaxxdaxabaxbxaxaxadxbadbxaadbaaaxabdbaadbdabxxaaaxbacdbxaxxxaaxaxabbaaadadbadabdbacabaacdacdbbabbccadbbbdbcbcdbxxadxdxaacxbaxbdbxbddxaxaxdxxxbaxxaaxabxxxdadxadaabxaaxxxdbxbadbxabbxaxabdaaaaaabdbadbdaaccbcbbabdadadbdbacdaxxxbdxbcbcabxaabxxaxxxcaxaacabadaaadacbdaacdbdaaaxxxdxacbxxaadbbxbxxxxadbbxbdxxxdxdxadxabbxadxbxbbdxbxxxbxxxbaabdxxcdbxaxxxxaaaaxxaxadxaxaaadxaxxdxaxbxxacacacabxcaacxcadbacbacdacaacbdaaxdaxaaxaxaxaaxxadbdbadacacdaadbbdaaaadaadbbdaaaddaabdbddaaabdaabdbaaxabdacbdadbcddbbaaaddbbaadaxbxaacaabaabdbacdbddaadaacbdaadaadacaadaabcxdbabxaxxaxbxbaabxxdaxxxcxdxaabxaxadbxbxxaxaxdaacbaxdxaxxaxxxxaxdxdxbxcbbdaaadbbcbdbdadbbdbxxxbcbxxbxacabxxccaaaaxbaaaxadxcxbdaabadbadbaaacbdbbaabbaaadbcaxbaxdxxxcaaadxxdxxaacxxdadaxxbdxxaaxaxbxxaaaaaxaxdxdaxaaxxccxcacbxbbbdxbxxxacxbxxbadaddbdabbacaabdabaacaacdbbacbxbdaacadaadadadabaabccdabdbaxxxbcaaxbbcbxcxxcdxabxxaxxaxaddddaaxxxdaxadaadbadbaddaaccbaaddaacaxcxdaaxxdbxcxabdabaaadbcdaadbbdabaaabbcdbcxxacaxxdxxaaaaxxbdxaxxxaaxacxaaxaaxbxxbxxxxxaxaaaxaxcxcxxxdxaabacbabbdbddaadaacdbcbdbdabdabcabbdaababbaadbdbcaaaacbaabdaaaacbabbbaxxxdabxdxbxxbbxadbdxbxxxaaaxbacxcxddaxxaxaadbcxxadabxabxaxxbxxcdbdaaabbdaaabbaadacdbdadbcdbdbcbaacbbdabcbbacaxaxbxacaaacxbxdbacxaxxbxxxabbbxxxbxbxdbdxbdaabdbacdaadbdbdbccbbaaxxaxabdxxdxxxdxaccxxaacdaaxxbbxdxcxxcaxxxxcbacdbbdxxdaxbaxaxbbxcbxcdaxaadbcxaxxacbxxaabdbaxxdabcxdxdxbaadbacxxxxaxaxxacdxdbbababaadaabdbaaaaadaabaacddbdxbabaadbbbbbbbbaaaacbacdaadbdaabdacdacxaaxbxbaaxxdxaacxxxcaxxdxxxabxaxcbadabdxxbccxaadxcdaxacxacdaxbxxxxbdxdxxxaadxxbxaxbaxxbadbacbabbcbdbbddacbadbadaaaxaxcaaxabxacxbcxbdaxaxxaabcxaxbdaxaxdbcaacxaxcxxaxbaacxxdabxacxdbcaxbbbxxxaxbbaxxxbdbxdxdxacaxxbaxadaxdaaadbxabacxaxaaacxaccdxdaaxdbbacxxxdxxxxacdxddxdaxaxdxxxbxxxxadadbadaxcdbxaxacxbxxcxxxbaaxaxdadxaxxcdaxaaddxdxaaxaxaxxcxbxxdxaddaaabxaxaxxxxxxadaccbxaaxbaadbdacadadadbcbaadaacbdaaxxxbxxbxaxdxbaxxxxccbacaxxxaxabadxdabbabdbbaacadbcdabdaaacacdbdadbadbdbdacbxxxacabdxdxcbcxxaxdxxbbacddabbbcaddabadaabddaaxxacddbcbddxabaaxxaaxxaxxdxxxcdbaxaaxxbbxdbcaaaaaaaaaadaxaxxbdxaxacbaxabxadxaxbcbaadaadaaaaabdbbaadaxaaxxbaxdbxacbcbadxaacxcbaaccbdbcbabdbabaacbaxddxxxxaxaacbxbdbdabxxdxaxxxxabdabdbxaaxaxxbdabxaxxccxaxxxxcxxaabdxdxxbdaaaaaaxxxabbaaxaaxadxxxdxaxadbdacbabdbaacbaddbxbxdxdabcbabdbdbbdaacdabdbbdabbddxxaaxabadaxaxxxaxbxxaaxxacbxbbdxaxxabdxxdaaadaaccdbacdaaaaabaacbbbbdadbabxdxxaxaabadaadadbcacbbadacdaaaaccacabdacbbxacbaxbxbddxxxxxxdxaxcxcddbaxxxcbaxxxaacxbabxdxbdxbbbdbdbdaxxdaabbbddbacbaabbaabccbacbaaadacbbxaxbxaaabbxdxaddbxxdbbxxxbaaacdabdbdabadacaaacaaxxaaaxdaaxxxaxxdbaxacdxxbbaxbdbdbxxbcadadaxdxbabdxxxxdadbadaabadbabdbaddbbabdbdbaddbxadaadxdxacdxdxbdbacbaddaaadbbdaaadbdadbaacbabdadaaaaadbacbbdbcxaxxadacxxaxxcbdbaxdxcdaddaaabdbbacdbaaadbdbabacacbaadbxxaxxxaacaaacdbbbdaabbbdabababdbbxcdxxdacdaabaadadbdabbcdaaxbcxxacxxxaxcdxcdbxacxxxaxxxdbaaxdacaxxaxaxxxxxadxcaxdxxxdxdbaaaxaccbdbadbdbdbbbdadbaabbxxaxaxxxxaxxaxdxdaddacxadbdaaaaaabbcdbaabbbdabaaaxaaxdbdxaaxdxaaadbxxcacxaaxxdxdxaxbbaxbcbacbaaadbbaddaabdaaccddbbddbdbabbaadxaxxxxabdxddacaxaxbbdbdbdabacdabcddbdabadbacaacabdxxbaxbcxdbbxbbxbdxaadabxaxcdxaaxbbaxdabbddbdadadabaadbdaxxdbxxxaabbxxaadbdaaaacaxaxdaxdxdxdxcabbbdbadbcbdbdbaaxxxxcbaxxaaaacbxdbaaaacxcaxdbbbxxbxxxxdxxxbbaxxbxdadbxabddbaacaacdacaaaaababbbcadbbbdacdacbdbabdbaadbdbadadbaadabcbaabddacxxcaaaaaadbbcdddaaaaababcdbcddbaxbxxxacddaacbaacaaaddaaaacaxaaaxdxxxxbaaaxxxbdxabxxaabdaabccbacbddbbadabbcdadxxdbaaxxbxxxxaxcxxacxxxbaaxaabaaaaxxxcxxxaacxxbacabbdxdxdxbxadbdbacaaabacdaadaadaacdbbdbacadbbabaacaabbadxxadxxdbdxxacxaxxxxdbxdaxdbxbbxdxxaaaaaxxcaxdadbaaaxxbxxxbdaddbxxaxaxabaabcbaacbabbaaadbabbxxaaabaxbaaacaxbbadbdbxdbbxxdxdbxabxbaacbcbacxxxxaxbxxxacbxbbcbaacaacdbaaaacbaaabdabaaaddadabbbacbacbdbxcxbxxdadaxxbxxcaxdxaxdbaxbdxxbdbaxadxxaxdxbxxbaxcxxaxaaxbcbabbaadbaacadaacacdbabacbaadbbacaadbbbabaaxxxaacaxxxxadbbadaabcabaacbbabdbddbbdbacbbdbdadbacacabxaxxxcabxaadxxxxxcxaaddabdbaacbdbbdaabacbaaxacxbxbaxxxxcdbcdxxdadbaxxddxabxdadaaxbxxaxcdabxcxaxdaxaaxxxxaxxadxcdxxxcxxaacaacacacababdbdbaaadbxaaxaxbxabbaabbadadbdbcdadbacbcbxxxbaaxdxbdbdxdbdaxaxbdbbxxxdbcxxxabxxaaadbddbxbacadxaxxbaxxcdadbxabxdacdxaadbbxcabxaxbxacxaxacbxaxxxdxxcxxcbdxbxxaxxcbxadbaaxxxddxbxxbdabbdaadxaaadaxxbaacxcdaaxxxaxbdaxxbdxdacxdddxbdxxdxaxaxxxcbxxcacxadxbxabxxaadxbaxbxxxbdxaacxxcbxxdaxbxaxxaxcacbxaxxcxadxxdxadaxaxxbdacxdaxaaxbxcdabdaaabbcdaaddaccadababaabadaaadaacddxxxcxaxxdxbaxaxxcdbbxaxaxaaxbaxbdbxxxadadaabdaxaadxaaxaaxdxcdxccaaxaxxcxabdxcaxxaaxacbdxxxbaabdxxxdxxbdxcdbbadaxxbdabaaadaacbaabdbddacdbacbacaddbadbbaaabadbcbxxxaxxbacbxaacxbaaxxxcddbaaaadaaabcbadbbdbbcaadbdacbabcbaabbaxcdadxdaxaacxbdaxcxxbxaaaaaacadbbdaaaddaadbdaxabadbdxbaacdadacbbacbcdaadaaaabaxbdxbdxxbdbdaaaaxxbxaabcdbdaaadaacbacabdaddxxaabaadaxdbaxccacxacxxdaxxdaxdaaxcxbxacxaaaxaxdxacabacxxxdacdaaxxdxaxaaadbaxxxxaxbaxxxaxbbxxadbdaxaaxxbxbacabcxadbxxbababaabxdaxaxxdaxdxxxccdabbaadbaaadbaacaxbxxxaaxaxdxbaxxxacxxxcxxxaxbbdaxbdacdaddbabaacdbaadaaaacaaaaccbadabdbacacbaacacddbaabaaxxbxxxddxxcaxcacxdxxcdacbadxdbabxxbabxxbacbcaaaaacaddaacbcdabccbbdaxaxxxdaadabbcadbbaaddbbbdbbxcdxxxacbaxxxdxcdxxadbxbcdbxdadxaxxxdacdxaxxxcaxxaaadacxxdaaxdbbxdbddxaacaxdaxxdxaxaxxxabbadaxacbaabcaaacaaacdadbddaaaaaababdbbabadbacbcbaaabaaaccaababbbaabbbaaacbdacacdaadbabbxacdabadxbxxxaaaxbaxxxdbxaadxaaxabxdaxxdxxaxbxabbaaabaadbdbacbaaaacdaacaxadbaaxdxbcaxdbxxaxbddbxaxxabddaaadbbdabbdbacbdbdbcdadbdxaxdbxxcxbdxxxbbadaxaxxaaxbxaaxaadbxxcaxbxxxbdaaxxbaaaxaxdxxxbxbdaaxbdddaxxabacdbxxbaxaacbdbaaddbdaaabdbcdxacdacbabadabdbdaadabdbbcacacbcbcxxbxbbbaxaxxcadxdababaxbxxcxbacbdbdaaabccbdabcabadabddxbdacbcaabcdaadbdbcbacbaaadxbxxxacaadaaxaxxxaxxbxxbcxaaxdaaacadacdadadaaadbdbabacdbbacbaaddaadaaxbaacaxxabdabbxxxcdbdbacxxbxbxaaaxbxbbbxxaxxaaaxaxxbaxadbacbdbdaxxdbdaacbbcaabbaccaadbdadbbxaaaxxxbxaadabdxacxbbxbbcaxxxbcbbxaadbdbddbabaacbbcaaaaccbbcbaadaaaaacbaabadacaadaaaxxaxaxxxacabdaaaabdaacaaaaaaacdadaadabaaaxaccbxxadxcxcxdbxaaxxxbxcaxaaacdbadbadacabbddacdabbdaacbxbbxdaxxxxxbdxbaabaacbacbbaabdbdacdacacabbacdbacdbabdaddbdbdadaxbbdxbxxaxxxcxadbaaaaacdaabdaaxxabxabadaaxbddxxxxbdaababadaaacdabaaaabbbcxbxaaxdxaxxxaaxacdxxxaaxbxxcxcdxcxaxaaxcaxcdbcbbxdxbdxcbdaxxdabacbdaxbxacbdaaddbxxcxbaxbxabxxxxaxxbbdbxadxbxxdaxadxadaabdxddxaxdxadxddbxxdbbdadbadacaabadbaabaacaxacdxxxbxcxxdabxxaaaaaxbadxaxccxabdbxdaxcaxcxaxxxabdbbdbaacdaacdacbaacbbacacabcbabcaaadaaccdbbbdabbcaadabbaxaxcbdxxcxabdaxaxxadxcdxcxxcbxxaxcbxdbxxaabbxaxxbxbxaaabdxcbadbcdadaaabaaacabacdbbaccdbaadbacabdbbcdxadaadxxabaadxcxxxaxxxbccxdaxbaadbdbdbaxaxaaxbdbdxbxadbddbacbdbdaabcaabcdaccbaacdaaabaaccbacbdaaxbxxxxbdbxxxxxxxcbxxbxxddadbbdabcaddaxaxadxxxxdxabacaadbdaadadadddbaaacdbaaaaacdadadacacacadbdabcxacbbbdbdbadbdbdaabdacbaabcddbbaadaaxxxacbxxadacdbdaaccbaabbdxaxxcbaabaxbaxdaxxxxbbabxbxxabaxxaaaaaacbaabdadaabadbxdbaxxddbaabadxaaacbcxxdbxxaxbbabddacdbdabdaaabacdbaadbdacbaabbabbaadabcxxxcdbbxaxxaxxxaxbaxaaxdaxdxxcdaxdxxbaaaaabdaacdbadadaabdabxxaxaxaacbxxxbdxaxbdbbaxadaabxbddbxxxxadxcbxxdbbxaxdxaxxxaxxxaacacaacdbbaaadbdbaacdacbdbaaadaabbaacaaabcbddaaadbaaacaaadxdxaaabbaadbdacbxxadxcdbbxbxaxaadxbbcxacxacdbxaabxxxaxbaxxaaadacbbdaadaacaadbdacdadabdbacbababbbaabbadaaadaaaaabaaxacbxaaacadbdadbdbdacbadbaaabxbcbxdaaadacxcbaaccbdabaadaadbdbadbbdaabdbddbbbcdbddxacaaadbcdacbabbdabaacdacdbdbdbbbabaacbdaadbaadaaaabcdacaadbdaabcdabbdaabadaabadbadbacdbdadaaddbxbxxaaabxadacbdacaacdbacdadbabbaaccxxadxaaxbxbxdbxddadbddaaabxaaxbdaaaxxbaacxxxxxdbbdxxxacxdaxxxadbxdbxbdxbaadbdxbxaxcadaadaabbacdbaadadbbacxcbxbxxxxdaadxcxxxcddbdbxxxbxxxadbabdaaaxadxxadxccaxxxxxaaxxxdaadaaccdxdadadbdxacdbbbxxaccxxdxxccxaxcxxxaxxabaaxxxdxxabaadxxdxxcaxxxxxababbxdxacabxxbxbacbxxaxacdacxxaaddxadxbdxxbabxcbxdaaxabxaaadaxaxaxaaabaacaaacaacdaaaaadadbdxxacabxaadadbaacbacbabdaaddaaccbcdabbdbabacbacbdacabdaabacacaaacdadabacbdabbacbacabcdaabbababababaacbddaaaaacxdxxxcxdxxcxaaabdbaaaadaacbbaabbxdxbbdbxxaxxbbxxxxxadadaxxadxaacdaxcxdadaaabaaaacaaaaacbdbadbdbababddacacadxaacaadbddaadacdddaacdbbaxadxaxabaxdbabdxacddxbxaxxaaaabxxbaxxdacbcabaabaxbxbaxxxaxdacbcdxdaaxdaaacaaxxbbdbbdxxcxxxaxaacdxadxaxaaxxxaabxaxcxxcdbxaadxxxbaxaaddxadabacaaxbxaabacdaaacaxdxccxxxaaxxaaaxacxxxaaxadxxccacadbdaacaddbccabadbbdaabacbdababaaaacdbbdbbdaacaaadbacbadabdadbxbxadxaccxxdxaxabaxxcbxaaxcxxxaxaxadaaaaaxcbdbbbdbacbdbdbbadbaabacdabdabdaaaacadacbbddbbbdbdbdaadbbddxxbddaacxaadxxbaxxxxaadxcbxxbaadabaacdadacbbdbdaxabbxaacbacbdxccbaaabbaacacbdbcbbaadaxdbaadadabaacaaaaabaaccbcbbbcxxbacdaxxbbbxxabdbdxdxdbdxadbadaxaxxbaacdacxxaxbdxxabbaxxxxxxbacaaaxcxaxxdadaxdbdxxbdxxxxbbbddbcbxaxabdacdbbaaadacdaaaccdbdaaaacbbdbbaaaadbadbdaaaddbccbaxaxbxxxcaaaadbabbacdadabbcdaaccbdbaaddbcbaaacadadbaaaadbadacbcdaabdxbcdxaxaxdxcadxbaxbxacbdacxxxxxxxxxxacaxadxdbcxxaxdbbcdaxaxcxaxabxdxaxxaxacdbbadadbbadaaaacadbbbxcddaacdaabababaacbbbccbxbbcaxaadbxxxxxbbdbcxxxaaaaacadbbcbdbbdadacaaabaadbaadacdaacdaabbaaaaabaadbbbbdbbaaaadaaabbadaaacadaadacdbxxdaxxaxbacbxxxddadbdbacdbcadbdbadabaaaaxbdbbaaacacdacbcbdbadbdadbaaxaxbxxxadbdxdaaaadxdbxaaxxabbdabaxdaaaxaxxbxbdxabdaaxbxbcbadxaaxbddbxacaxdbdxaaaxxxxxxxdaaxdadbaxxcxxbacxxaaxxbdaadaxdaaxxaxxcdbxcdacdaaxaaddbbaxbabadxxxaxbaxaxxxdbxxxdabdacacxcxxaxabdxxadxcaaadbdadabcbdadacacbcxacbxbxxxcdbcxxxbxdxbxdxaxaacxxxdaaadbaabbbaadxxaxababxxxxxbdbabddadbaaaxbxxxdbxdxdaxxccbdbdxxxcabxdbxbbadbxxaxbxxbxbdxdabxdaxbabxdxbbaaacdbdacacaadacdbbadbdbbaaaaabaaacxbdxxxdacaaaxcadxxaaabcxxaxdaxbxxbxxxaacxxxbaaacbxaxdxxaaxaxxbbabbdxdaxxdaxdbxxxdacdbxaabcbbxxbbdaadadaadbaccbdabcbdabdbcaaaadxdbaaaxdxaxaxxaacdxbbabxabadbdxxadbaxaxxaxxbaacbxxxxaccbacaadacbaaadaaadbaabaadabbaaaaabaadabxxxdbdbdabbaccdaxxaaaxdbccxxbxaxbxaaabxxxabcbdxabbdbdaabaadbababbdbacdbbdaaaaaadbbbaaaadbaadaabacxbabacabcaabaaaacbbadaadbcabbabdbbdadacadbdaddaadbcbdbaaddbbdaccdababdaadbaabacbcabdbdbacbcxxbbdaaaxxxaaxxacxxxabxdbxaxxxxbaadxxaaaaccxacaxxadxxxdxadadaadbadaacabdaaccbaabcaabdababdddbaaxxbaxxxbbxddbddbaaaacdaaaaaaadaaadbadbacxaabdabcxxdxxxxcxdadxxxdbaaxadbadbaacacdbadadaadbadaxcxxdxadacabaabdabadaabdabcadbdbacdaadaaaadaadacadaabdabdabacdbcbdbaaacbdaabadaaacdddaadbadaaaaaaabxxbbaxaabxaxaxaabcdbdacaadaabdaaaadaadaaabbdbaaaaabaadaaddaacxxaaxbdxadxbxacxaabadaxbxxadxaxcccxxxcxacdxaxxaaxxxbxbbxaxxbbxdbxxbadaxaxadabdaxbdxaxxcxdacxdxbadxxacxxxxcxbxbdacbacbaaaadacaabcadbaacbdbacdaaacbaadaacbdadadabdadadacdbxdxxcaxabdaaadxaacxxcaaxxxbacdaaxxdbaxxbxbaaaxxbbcacdadacdbacdabacabddbbacaaabababaaadaxxadadxxddbxadacxxaaaaadabdaacdbdaaadbdxbxacaacaaacaadaadbdbcbcbdbdaababddbdaacddbdabdbbddbbdbxcdbbaxdbxxxxbbadaddaadxxxadaxcaaxaaxxadbxbxbcxxxaxbaxbxaxbabxxxaxdadbdxadbacxxacxbadbaabdbaadacdbacbaaabdaaadacabaabbbacdbbaaacdbdacddadxbxdbdxxcaacbcbdbabdbdaaacadbacdadxxxcaaxbxxxxxaxadxxxadxdxacbxcaxabdxabxaxdxxdxabaaadaxxbdxbbcxxbxxacbcdbaxdacxbdaabdxxdbxdaaacdaadbdaacbcdadaabcabdbaaabdbddacdxacccdxxcdbxxbxaxxadbdacaaxxbxddacabacaadaadxxcdbdbxddaaaabaaabaababbxxxxcdbxxabxxabxdbxxcbaxxaacxxaaxxbdaxbxbaabcxaaaxbxbxdxxbaxdbxxdaddabdxaxxddabcaabcabaadaabacdbaaababcaxxxxbxaaaxbadababdaaaaaacacddacdbcbdxxbaxxabdbabxbaxcbxabacxxdaxdxdxcdbbxdaxbdbxxxxaxaxxcdddacxxxxdxbxxxxaxaacdbdbaadadacbbdaaacaacabaacdaxxxadaxcbxxcbdxbxxxcadaxxaxaxbabxdxcxaxxdaaaxxxccbbbadbbdbbdaccbdaddacaaacdaacccdabxdbxbdxxxxabxbcxxxcbbxaabcabxddaxdaxxdxcbxacxdxbaadxaxxadbdbdadaadbdbddaadbdbabbdxaabdbcabaaadabdaaabaacbacbdadaadabbcacadddaxadxbxbxxaaxcdadxbxxxbacxaacxadxxxxbxdbdaadbxdxaaddacaadaaabbaababacxxacxbxcabxxdbxaxdbaaacbcacbcadbaadaaadbbadacaaabbbcdaabbabbaaxbaxdbxxaxcxdbbcdddadaabbdaaaaccbdaabbaaxaxcaxbaxaxxacxxaaxxxcdaaadaaaadaacaababacadbabadbdbdbxxdxadbxbbxxaacadabxbxxxxbadxbbxxxxacxxacbxcxaxbxbaxbaxadaxbaaxaaacxaacdadadbadbdadacbaxxxdaacdbdaxabbaabaxdaxcaxaxxcxaaxaabxxacbxxbacxxdaaaxbaxcaxxaaxadadxxdaxdadaaaaaacadadaaacaddaacccadaxxccbbcdbaaaaaaababddaabbababadacdacbdaxdabxaxaxabaxxabxacxdaxdaxababaacaxdxxaxxaadaacaxabaxxxxxbcbxaaaaabacbaaabbdaabbbcdbdxbaaxadxaxabxacddaaaaadbdbaaadaaddaxbabdxdacxaccxacdbdxxxddxabxbxxbacdaabdaaadaaaaaabbcddxaadaxbcxadxxaaabxaxdbxdabbabaxxxxxaxxxxaacaacabaacddaabadbaddbbxxaxbbdbdxaxxdxxaxdbaaxxxxaxdbxaxbdaaaacbdbdaacdbacacaxdxdxxcdaabbbdxaabxbcxdbdddaxxaaxdaacbdaccbadaabacadbdabdbdbxdxbaxdaxaaxbbxabxbddxacccdbaaabbbaabadacbddaaaccbabaabdadxdbaaccaaaadbaaaabxxbdxxcdxxdadadabdxaxdxxxxadxxbxacxdxxaaxxacxaxxacbbxxbbxxxxxbxcabaaaxaacdxaaaxxcxdaddbxabdbaddacacaacbddacaadbcabaaaadbbcdaaaddbdadbdaacdbbaccxdxxdxdaabacbababaaaxxxxxaccxacxaaxacxxdbabcxadacccaabaabaaaabbbdbdbxabcbddaadbdabbcdadabbaaaacbabddbdbacbdbadadadbbdadbaaaaabbadbabaacbbacadbbabdbdbaaabdaxdxxbcbadxdbdxaxbxxbaaaaaabbcacdabaabdbbaaaddbacbdddadaaaddabbadbabdaabdbbddadxdaxxbxaxaxxxbxcbdaaaaxxbaabdaxxdxcaxxxxdaxxbcbdadacbadadbdaaacbacdacbdabxxdbbbdbaaxacbaxacababbdaababbdbadbccaadaaxxaaaxaxbaaxdacbdaaxcxdxdbbbacdaxaaacdaacdadbbbdbcacdbadbcbbxdxxxaaaaaxxdbxxxxaxxbdxaxdaaaaadacdadbbabccdbbaccabddaaacacxddddbaaxdaxbadaccabdbdaacdabdbaaadabdbddxaxbdxbcxxadabbdaadaaaaabdacdaaabbaadbxxbaxxcxdbxabdabcdadaaabcbaaabacbaaabdbxbxdxaxxbdxxbxxxxaxdaaaccxxxaaxaaxbdbdxcxaxxabxaxdxaadababxxxaxxbbxdbadadbdbabadabbacaadadaacddaadabcdabaaabdaabaaaxxabxaxaaxxddxadxxcaaacbbacxxbxxbdxbbadxbbadacaaaaacbacbdbdbabbxcbxdaaxdbcxxxacacdacbdbdbaacccbcbdbadaaadabcabbbdadadabdbaxacxxxadaxxxxxdbxxcxaaxxaxcxaaxxbaxdxxbbxxcxxbaaxadxbxcdacaaabacacddacaadaacbacdbacbaaxdabxaxbxaxdaxaaaadaaadacdaacbabdadaaaxxxdxbxaxadaxccdxxxaaxddxxxxadaddaaabbadacbdacdadbdbxxdbbadaxcxdaaxdaaxbacdaaacdbaabaabdaabadxbcaabdacadaadbdbcaabaaaabbxxxcadbdadabdbadabaaaaaacacdacdbaccabdbccbbdbdbaaadxxbaddaabdxbxxdxabbadaaadxcaxdadbadbdaaadxddxxabbaaxddxxaadabxxaxxaxcacbxacbcbaxccbxaxccaaadbdaadaaccbcxdxbadbxxdaaxbxaaadaaacaacdaccaacbdadaaacdxxabxxbaxaaxxabxxcdxacbdxxacbddacbbaacaabdaddbdbddacbbbdbdaacdaadaaadacdaaacbdadaadaadbdbxxbaaxbaxabaxadbaxdxxadxaadbdabcdacxabxacxxxaaxxaxbxaxxdaacdabaadacbadaacbbaadaacbadabdbacaxxbdxcxxxbaxdxxaxbbbddbbbaabadbccdbaaababbabaadaaabbbaaaadbdbaaabbaxxaxcdadbacxaaaaxddbacaaaaaaaabacadbaacbcddbccbbadbbabbcxxaxxdxbxdxabbaxaabxaabxbxxacddbxbxbaadaccdbcdbdbdbdacbbaadbaaadadbxbbbcxaadaxaacxxabxaxadxbddxxxacaxxadabdaxxxdxxbabdbaxcdxxaxbdxbbddbacddbdbaaaaaadbbdaaccdaadxcaxcxbxdaaxxbxacaaadaxbaxaxcxabaxbdxxdbabaxxxxxxcaabxxxdadaaxcaabdadxxxxabdaadxbdbaxbdaaacadxxcxxcbaaaxdxxbxacabxabxbxxbaaxbxbdadbxxxacxxbdadabaabaabaaaaabdacbaabbbbadacbacdadaaaaacdbaabdbaabadbcbbdaacaaacbadadaaacaabdbbbdabdbaaabxbxaxaaabbdabdaaadbabbbddaaddxdacxdxxbxdaccxbaxaxxbbxadaaaxbbaxaxxbbxxdaxxbdabxdbbaxadaacaaabdbbaabdaacbdacbbabacbdaabacdabacddbbdaaaaaaaacaaaadaabdbbxdbxbaxxdbaxdxxxacxdxxxaxxaxbxbdaxcdacbxaaxbcbaaxxabxaxbxxdaacbaaadacdbbbdbaacbcbcddbbcadxbxaxxbxaxxxbaaxdaaaxcadaadxaxdxdxadxbdaxaxdbxaxbaxdxcbxxxxdaxaaxdaccdabbdbdacbaaaaaadabaaaaadbxbxbxaxaadxxxaxbxbxaxaxxxdaxxbxaadbxaxabadxdbaadbxaxabcaaaabadaaddaacdabbcaxxxaaaacbxbdadxdbxaaaxbacxxdacbxaddbxbdxxdxxbbbddacdadabbacbaacxcxdbdxbbxdbxaxaaxcaaddacdadbdbadacbdacdaaaaaccdacaxabcbdacacadabbcdbacadaaaddaacaaxadxacxdaxbxxadxbaxcxbcaxxaaxbbaaadxdbaxcxxabbxaadbabbaxcxbadxxadaababaaabaadadxxxdaxbaddaaaadadbbcdbbacbbdabadbadxxbaaxbbaxcdbabaxxxxaxdaxxcdxxacxxxbabdxaaxcdxdaxbacbbdbdbbdbcbbbdbbaaaadbcbdacaacbaacbbacaacdbaabxxxdbcbaxxcacxbbxxbxbxacbaxaxxxddadbxxxxaxxabxxxacbaacdbbaabdbbdadbbabaacbdaxbxbabddxacxacdaacbbxbxadxdxxaxaxcbxxacxcxadbxbxaacbaxaxdxbxxcbxxdaaxbcxcbxbddbacacbdbdbccdabacdbcdadaaxdaxbdbaaxbxxxbdbxxdxxxdxdxxdbaaxaacxxxxxaaxxacbaaaadxdbcxxxxxbxcdacaacdacaabacaaadaddxxxdaacxxxcxxxxcbdacaaacabdacbcbaaddbacaaaaaaadbdbaadbbdabadacbbdbacdbdxbaxdadaxbxxxdadbdadbdaacdbadbdabcddbbadabxaxxcbxadaxaaxbbaxxaxxbdbaadaxbdxxcdbcaacacadabadbdadbdacadaaabxbxxabdaxdxxdxbacbdbabbbbcbdbaadabdbdbdaaababaxxxbdabdxxbdacabaaxdaxaaabxacdadbabbadaaadacdbdbabdbadbdbcdabbaaacdadaabbaaacbbaaabdbbdxabaabdbxcdacxxaxbdxxcabcadaccdadadadbaaaaabadbacaxabdaaxbacxxdaxdaxbxaaxxxaxdabaaacaacaadbaacaabbaxxacbcaxxdxadxxdxxbaddaabbadbdaaabdbxbabaaaxaaxcxaxaxbbaxxaxxabxxdbxaxbbxxxaaaaacaacababadbdaabdadadacaacbacdaabaacdbadaabdbaaxadabdbdbdbdaabacaaxdbxdbxbacdbacaxdaxaaacxaaaadbaaacdbbdbaacbadbadbddaadaxcxdxbxaxxbaacxaxcxxbbxxbaxxdbdaadxaaaxcdbbadaadxcbaaxxxaxcdxxcdbbaxaxaxcdxxxxxxaxbxcxxcxdxxdbxbxaaxcbxxdxbxxcdadaadxaxaxxaxcdbdbbcdaabdaaadbbaddxxdaabxaxxaaaaacdaddaaabbbcdbdabcdbccbdbdxxaxacxbcxddbxbxxaaxxddxxcxaxxdbadabbdbdbaaababbdbxabbxabxbxxcdbaxxaxbxabaaaccxbdddbdaddacaabbababaaaaadbaxxbdaaxadxxbxxdxbxbbcaaxbaxabxabbddabaadaadaaabdaabdxdxxaxdxxaxabdbdbadxbxaaxbdxacxaaxxxxabaxaxxxaxxxddxcadxxxabxxcaaxbxbabdaaaxxxaxxababxacdaabbbdacbccadbcdacdabbacadxcdbxdxaxbbxbaxbdaxxaxcxxxxbbdbdabxxxbcdxaaaxbxxxaacadaaxaxabxbabxbxbdxxxaxdbxaacdbadbdbaccdadaacdacddaabdbdbxbabadxdaxxbaxxxbxaaaxaxaadaxbaxadbdxxdxxacbddbaabaadbcbacbdbadbdacaxxaddaaaxxdxaxdxcbxxccacbaacdbcbbdaacdadaacaacaacacadbcbdaadaaaadaacdbxcxabdxaxcdxxaxcaacbdacdbcdbbadbadaaabddadaaaadacaadaadabxxxcxxaaabaaxadaxdxaxbadaxbdaaaacadbaabaaacbaaadbaaxbccxxcaaaadxaxxacxxcxaaxacaaaaxcxbdbbdadacxaxacbbaaaacbxxacbdxaaccaxxdbadacdabdadaaacacbdaabaabdabcbbbbbcaababxdbbxxbxacaxdbxxbdbbcacddadabadadbbbbadbdbcdacdxxdxxacxdxxcbxxdxxxxaxdxcxxaabxbxxxbxaxdxxxdxxaxxabaxxbaxxxadxxxbxdadxxxxxdxaxaxxxaxbbadxxdxdxxabxxacbcacabdbbacbaaadbbaxaaccdadadaxxaadbbxaxaxxaaxaxxcbdbxdaddababbacddbaccbcaaxaccaxadaaaacbabababdacababbcaaabbadaabbadbccdbxcaxadxdbxxxxxxxxaaadadabbdacbacaaaabaxdbbdxddxxxxbdabxxxdadaxaxdbxdxaxdxcxacbdaacdbxccbdaxxaabdxccbdbxxbdabacaadaabaabdaaaacaaaadbdxxdbxdaaacxxxxxcxacxdaaadxxaxxxcxdbdxdaadaxbbabdxxaxxacaacacdabbaabddacbcbaaabdaababbdabaadababdbabadbddaaaaxaxxaccaaxbxxabdxabbxadaadbaaxdxaaxaxxbxxdbaadaaxxaxbxbabadxxaxxxbadaxdbdxxcbxxxbdxaaxxcxxxadbbxaxxbxbaaxbdaxdaxbabdxxxxxdacbxaxbxaaxaxxxdxaadaxbxxbbxbcdxxdaxaxxaxxbadxcxxxaadbbdxdxcxbxbadaddbdbadadaabdbaabacaaadaxxxbdxxxxcxbbabdadxaxadbddxadxacbaxcbdxccdbaaabdaaabaacacdaaaabbcacaaaadadadaabadbdadadaacccaaaadacdxdaaacdbcadaaaacbdacdaababbdaacacaaadabacdaccaacacaadacacbbdbacaadbbacdbadbcbaaaaabdaaadbdbcbdbxxxddbcdbdbaxaaxaaaxaxxaaabaxdaxbaxxdacdxaxbbbdxxxxadaaxbbbxxacbxacbxdabdxxdxabxxaaxadxxbbaabaaabdacaadaaacdacacxbaxcxdaxaxxaxxxccbxdbcbxxbdxdxxaxaaaxdbcbcbaadacbaabaacbdacaacaabdbaaaddaaaaacbabadbadbdbbcdaxbxxdxdaxbxaxdxcdxbxbaaacxddxaxxxacdaaxxxxdbdbdadaadbacdaadbdabdabdbaacbaaccaaaabaadbabaaaabddaadbbaabaacbcxbbbacxdbxxabbxxxxbaaaxaaxxdxxxaxadabxxdxcaxdbxaxcxabacaxaxxxxadaxbxdxbaxxaacbdxcababaadaaxaddbabaxxcdbxacxxxxaadacbdaacddbcaaaddbaaxdaxcxxxxxbaxdxxadaaxbaadacaadbabdbacdbbbacabdbabdxxxacxdxaaaabdbdaabbacabcdbbdaabaaaaaaaabdbadbcabcacbbbdaccabacacbdababadaaabacacaacbabbdaxcaacadaccbbdbdadadbbbbadaaccadaadacdxbdxaxcxdabadaaxxabbaadabddbbbabadbxxxxdxacxdxbxxdaddbbacdbaaadbbcaadbbbdbbdbabdabcacdbbdaaxbxbbccdxdbacxxdbcaxacaadaxxxxxdxdbxaacbaxxxabaaxcaadxcbxxxxxcaaaadaxcbxacabaxbdaacxbxcaaxcxaadxxacdxacxbxxadaaxcxcxxxaadxxxaaxbdaxaxacdabbdbaxxxxaddbxaxdbxaxbxxxddxaacbbbxbxbxxxxxdxbaabdaxxaaaaacdbbacbdaaacbbddbbacxxxxaaxbdxbxbxdaxbxadxaxxdxadacabdaabdaacdbbcdbbdacaxaadbacdacbxxadxabdacxdxdxcaxxaaaadbdxdaccaaabadabdadbaadbcdbaabaadaabaxadxcdbxbdbaadxdabaxxxbxbaxbcaacaaabaaaadaacaabbaaacxabxxbabdxbaadxcaaxaxaxbxacxaxdaxxaadxdbxcaxaxaxcbaxdbxxbxcaxxaxaxxaddaxcbxxbddaaaaaxdaabadaadbadabaacadacaadxxxxadadxacdbxbaacdabxbdacxxxbdxxdbxxdxaxxaxcdbxbxaxcxbaxdxaxxcbxaxaaxaxxdxcdaaxaxadxxxadxadxaaaaxaxbabxxabbcxxdadbaxaxbdxaxxaxxdbxabxdxaacdbdacbabbcdadadbxxbbxaxbaxdxdaaabcdabacacbdbdabaaacdaabdbdbadadadbabbdbadacccbaxacxaaaxbdxbdaaacxaaxdaadbbacdbaadaabdbaaaccdbaabdxdaadbaaaadbcxdbxdaxaaadaaaacdabadbccdbadbddabdbaacbaadbbdaaxxbabaxbxdaaxxxbcxxaxxxcxabaaacxxaxbxxxdaxbxaaaxdaxaxdbxdaxaxaaaxdbaaaacddababdaccdaacdacdacdbababacaadxxxxxdbabbadbabdaababbacbbdbaaxcdxdbxaxxxacadbbdbaabbbdbaaaaaadaadbaaxxxddbbaacbdaxabacxdbaaaxbacdacxaaxaxaxxdbcxdaaxxxxcbxxaxacaxxaaddxbxcdbdxaccbabaxadbxxabcbaxxcdbxxcxbbdacxxdbxdadxaxxxxabxcxxaabcdaaabadbdbadbbdaadbddaacbaxxaxxbxbaxxdxxdxxadbbaacbbcaaabcdaacdbaaddadacxxxaxaacbcacadbdbdbbdadbabadadaaxcxcxxdaxbxaxxbcxdxadxbxcaxxaxdxxddaaaaaababdaaadabbdacdbdbcdacdbacdaxbadacdbabbdbdbdbadaaaacadbdacabdaaadbabaabaxxxxcdbbxxbcxxaxdbbcdacbaacdaaadbcaaabdaxxaxcdacdxxxdxxxxaxxbaxxdxabcbxaxdadxxadxbaxxxbxaaxcbbxaacdacccbaaaadbcdacaadbaxxdxababxxdxaxdbxxaaaccbbdbaabdbbaacbdaaacxdaxaxbacaxacdbxbxbxxbxdaxbabxaxxxxxdxcxbxbcbdacaaadbdbadbaaadbddbcaaxcaaabacdbxxbxxxaaxxaaxcdaaaxaxxcaxcxxbxxcxxbcxdxxxbacxdbdaxdxxdabadbdacabdaaaaacdaaadbbbaacdacabacbbaaadbbdaabacbdxcxaadbbxccdxdxcacbaxbxxxadxxaaxbxxxaaxxbaaxabbdbcdddadabaaacdbcbxcaxxabxcxabxxxxaadxbdxaxxabaxbxxaaaxbxdxxdaxxaxaxaxxaxcxaadabxdbddxcdbdxxdaaabxxxdbxcxxxxxbdxbxbdbaddbbaadbbadabadabaaadbdxxacxxxbacaxdxxaxaxxbxbaxbxacxdadabdbaadbcadbabbabaaaaadbbdbbacbbacbbdbaaaxbdxdxxaacadxbxxxxbadaxdxadxbxcxbxdbdbbdbbxbxcabdacbbaaddaccddbabadaaaaddbbadxaaaaxxdxxaxbbbdbdbbaacbaaadbababxcdadadxacbxbaxbxaaaacbbadddaadadbdaacdbacaaabddadadaxaxxxxdbacaxbxxdbxxxabbcdxxxxxdxxbxacaxbbadbcabadbadacabadaaaabaabdaxaabxxaxxdbxxxxxcbbxxbdxxcdaabxbacccacbdabddbbaacbdddbdaaaadaaaacdbbabcbababcaaaaaabdbdxxdxaxdxcdxbbaxaaxxdacbdxxdaacdxbdxaadaxxdxxaxxbaxcbabxxdbxcxbxaaaxaxxdabxbdxadaaxxbcxbxxxddxaaacaacaabaadbabcbaaaaadbaacbxbabaaadxcacabxaxxbbaxbxdaxxaxabxxxcdxdxxbxxbdbbbxbxxdaxxdbabxbdabadaacxxxaxbxaxadacxxadbxxdxxacdacbdaababbdacacdbbxxxbxdacadbxaxaxaaaccaddbaaaaadbccbcaaaaacaabdbaacbacdaaaaacbabacaaadadbbaacdaddbaacacabxaaxxadbxbxbaabxbxdadxxaabaaaxcxcaacxabaaxacababdxdbaxbaxbabxxaccxxcxbcxdbaxdaxxbxaxxbxaxxaaxxdacadaxaxxaaabdaabbbdbbaaadaaaaabdaabdbdbdbaaabdbdbacbabbaacaaaacabbaddaaadbaabbaadaadaaaadbaadaaccbxxaadxdabcdaadaxxaaacxxdaaaadaacdbacbabdabaabaaabcdadabacbacbdbbdababbddbddaacabaacbabdacbbabbadbdbdbaaabdabcaaxdadbadbxbdabcbdaaabbadbcbbaaacxaacaxxabxaaxadxcxaxcdbdxdaxbadaxaaxdabadaabbbaabaadbdbabdbaxaaaxxadbcxcdbxxbacbbdaaxdxbaxxxcaaxxxxcaxabdxxxbxcdxadaxaxxbacbdxxdxaxaxaxxxxdxxbdaxxxbxdbxdxaxaxdbxxaabxxxdacbdxbaaxxcxbaaxxxabxaddxdacdxbadxacdxaxxaxdxxxbdbxxxxxadbabaabbacadaadbaaadbacaaaabaaaaacaadbdabcdbaacbdxxxxbxxbdxxxadxxcaaxxxbdxbaaaaabaacaadbacbbdbbadaadaxdxxxcaaxxadaacdaaddaabaabaabadacxdaxxxabadxdxdxdabxbaxabaabacaaccacaaaabdaadbdbddbbaxbdxxdaaxxbbaxcacdaaaaxaaaddaadbcaabaadabacbbaaaadbccbbaaaaxbddxaaaacacadbababaddabbddaabdbacaaxbaaxcdxxacxadadaabdacadbacbadabaacadadaaccdaaaddaxaxxcbxxaxaxaaxxaddbdbbdbabdacacacbaabdbdbdbxbbxbacxbdxdxaxxcabxcdxxxaaadxcxdxxxaxxxdbxaaxxaabxaxxaxxaxxcxaadaabxaxdxxaaabxaaabdxxxxxcaxxbxacdxaabxxadadaxaaxbxaaxcxaxxbxdbacdaadbdadbdbddbdbbxxxbbxadaacabaabdbdbaacbacbcbcbadbdaxxxxcxbaccxxcdbbxxaaaacdbdbadacdbdbbdbbadbaabcbdaadaxxxbcaaaaaadxaaaaaacdbbdaccbacdbabaddaaacbdaababadxdxbcaxaaaaxxaxxdxbxcbdbaaabdbaabbaadadaadbdadbcbbacbdabadacaaxaaxxacadaxxbxxbbbxxdababbdaaaacabadbbbadabacdbbdadbacaaabaxbaxxaaxdbxaxxabxxxaxxxaxaxxaaxbxbxbxdaxaaaadbababaaacbcadbcbaadabdxbxxxbaxaaxxdaxdaxxadbdxaxdaxdxxxcxxxaaadaxbxxaxcxbbbxxxadabaxaaadxxxccdaabbdxaaxaxbcacxxdbxcbcxxxdxxaxbbdbxbaxbxaaxacxbacxaaaaxdxbxaaxxbcaxaabacxaxacxdxdxxaxcdaadbdbdxabaaxbaxxddaxxcbcaaxaccdxxxaaxaaxxxxaxdxcxbabdxaxxxdaxxabxbabxxxdbdbdabaadbdbaacdbacdabbbadxaxxccaxxxbdaacbxxcbxxddabadbbcdbxdaxaxaxaxbbaabaaacdacaaaaacdbdbdbbadacxaaabaxbxbadaaaabxxdabacdaadaccdacbdacbdbacaacbcdaadabababadbdddbacbcbcddaabbbdbdaabadabdaaccdaaacbbadbbxcdaxxxaaxdxxxxxadabadaadbdbcacaaacbcdadacaadxbbxcxxaxdaababdbabadaadabacacdadacxaxaxaaxdbbaacddbbdaabdaadbxxbxxbdxdadxaaxxaaacaaabacadadaacddbdacxxaaacbxabaxaxaxbxadxaxxcbaxaaxcdxbdxdbaadbxxdaxaxaxxxdxddxxdaaddbaaacabccdbabadbbdaaaxaxacxxbxaaxcxxxxxabbbdaaacaaadbdaacdabaacbccbaadbdaaaxxxxdxbaxbabdxaaxadxdxcaaxaxbaacxabbdbdaaacaadadddabadacdbdacacdbabaaaddaacdaabccbdbddbxxbxdaxadabxadxaccxxdbdxcbaxdbdxxabaadabdbddacdbdacdbcbdaaacadbdbbcbbaaaaabbdaaacaabdaacaddbxxbdacbdbdaabdbbaaddacdaxxadaadaxxxxdbxadbaaddaxdaxabcxbxxdbbdabdbabxxxxadxxxcxxxxbbxbaaacxdxxxbaxdbaxbaaacaxaxbbdbddadbacbdababccbacdbbaccdaadacaaaacbaxxaaxxaaaaxxcdxaxxadaxbdbacaxcbxbxabxxxbdbdbdaadadaacbadabaaddbdacbaaadaacdbaadaadbcdaacaadacbcdaadaxbccdadadbdbbdadaaacbdaaaabxxxdadaxxaxdxaaxbxaadaxxxacxxcxdaxdaadxxxxbxaacbdxaxaxxadaxbxaaxacxbxxadxxxaxbxbxaxbaxxdbdxxdxxxadxacxxddxxaxadabxaaxaadacbcabdxccbadaxxaxdbcxxxxbxdxxxbxbxdbabaxxaxddxxxxaacacdxxxcxaxacxadaddabaacbdbdadadacbaaaddbabdbaxaaadxaaxxxbdxxxxacbxacbbaadaaaabaaadbbdxcaxxadbxacdadadxcbcdbcdaababdbdadabdbdacacdbdadbdaaabbdxabbxxdaadxababaaaaadbdabacabadadbabadbdbaaabxabaacxdacdxbxdxbbxxaabxadacbabdaabxbaaaxabcbxbbaaadabaaaaabadadbbbdbaddabcadaacbcbacdbadacdacdbbddaaadddaaadaaaaaacbaxaddbcxdxxaaxxbaxdbaaxaxcbddabxdxxbaaaaacacbacaaababdbbddddbddbddaaaadbcdaadacaadababdbbdbaaacaaaabxxdxaaxxxxbdxxcxbacdbaaabadadbdacdbcacaxxxxadadxxxxdbdxdaxaxacacdaaadbbdddacdaacdaacbabadabaccbbbbaddxbadxxxxxxdxaacbdbdacbbdacabbdabxxdbxbdbxxdaaaxxxaaxbxxxxdxdbdxxabbcaxxaaabxaacbabxxxaxdxxxxbaadxdadbddbdbccbdadbdaccxaxxxcbaxababaadaacaaadxdadxxabxxdbxaaxaxxxdbdxxdxcxaxabbxdxaaxdbxxcxxxbxxxdbxbxcxbxaxcdbxacxdxbdaxbbaxxcaadbdaxxxaxxdxbbaxabaaaaadbabaadbcdbacdacacaacbcbaabaaxcbabbdbdxxabdxxxddbabbxxbxxxxxabxdadaxdaacaxxbaxbdbabaxxbabadaacbdadadaabdbdbdbdbxbxcbabaxaxxccxaadxcadbxbdaxxacxabxaaacxxxbbaaxxxabxbbcbxddbdxddaxxaxacxaxaaxxxxxxxcxaxdacbabaxxxcxdbaxxaxdaaadxxcaaabaadbaxxbxxxxxxaxaxcaxxbaaaxxxcadbxxxcdbdxdxbbbbaxxxaxaaaaabacaaxbaxdaaxdaaccxcbdaxxaxxabbacaxabaxxbaabdbdxxbaxaxxaxbxdaxxcbxddbaaaaxaxaxdxaxcdaxdbdxcxxxbdxxdaacaxxxbaaaxcdadxxxabdbxxxxxbadadxdacdxbaxabaaaxaxxbxxxxdxcaxxadxdbaxacxxbdaaxxabxxaxacdbbaxxbdabbxxxdxdxddxbbdbxxxacaxdacbdabdacadaaacbbdaaabaaaabaabbbaacbdbdxaxxbacbbabcaadbadbabcaadaabdaddbbaacadbaababbabaadaxbaabaacaacaaaabacacadabbaaaaaddaaaacaaabcbadbaaacaaaxxxxdxxaxxaaxacxxadxxdbxcxxxxaaabdxdxxdabxcbbaabdbaacaacbdbaabdbaccbaaababbxxdxcacxaaadbcxaxxdabcaaddxxaxbxaxacadaaxabxxdaxxabxabdbababcaaccbcaacxbdbabaaabdacdbbabaadbdbdbcbabaaxdxxdddxcxaxaaxxxbbxbaxaaxxxaxxdaacxdbaaaaaaxxdbabaaacaacdbdbabbcdxdxaxadxxbxxaxaxxaacbaxbaxxcaxaxaaaxxxdxdbdaabdacddbacacbadadabbdbabbabxcdxxxxxdaxbcdbdbddbdacdbdbddxxcdxdabdxaxadbaxacxcxdbxxxdaaxxabxdxaaxxdbbbbaccdaacacdabaacbaacaacdbdabdbdacbbbaacdbxxcddaaccaacabacaccbdaaaaaaxxcaaxaxaxaaxxadbabaadbacaaaaabacbcccabbbbaccbcddaaacdaacabcadaaadaxbaxcxabaxabxxbdxaadbxxdxcdacaxdbbxbcxbdxbdbxaxcxxxcxxaaaddbxxxadxaxaaaxxaxbxxbdbxxadxcbdbxadbxaxbabaaxbxabaxaxbaaxxbadaxcdabaxxaaxbaxdbbxxxacaxdacdadbadbaxaxxaaaxxbdadaadxxbabacacaaabdadaadbdacccadacabadxbxxadxadbaxxcxaxdxxxbxdxacacdabcbbbaaabaaadbaacbabaaabcdabaaabdaacbbabcdacadacabddbdxbdbbxxadxcxcdxdbaadaabacbbcacaaadabddaacaabbbdbaabcdbaacbababadbxxxxxdbxxacbbaadaacbdaabaabaadabdabacaddabxdaxccxdaabxaxdaxxaaxadabacbdaxdacxaxxbbxdaxaxaaaxxbxabxadbabxaxcbcadxxaxxdbaxaxaxaabdxbacdxxdxxxddaxxxbxbadxxxaxaxxdxbxbbxxdacdaxacdaxbdxbaxaxcbdaxdaxacdaxxaxbxxbadaaxdxbbdxxabxxbxbdaaxxabdabaaaaaadbaadbbdbddaxabdabdbxdaaaxbdxaaadadaxxxxxxxxxxadbddacbxxbaabbacxbbxaxxcdxbxdxxaxxxbdaxxaxxbbxxxcaxdxdxcdaxxacxcaaccxaxxaaadxcxbxxxbxdxbxaxdbbdabxxaxadxxxaxaxxbdbdadxadaxxaaxbxdxaaaxdxbbxaaaaxxbaaxaxdxxacxxxxaxxbabdaxcxaxaxxaxcdxxxdxdxxxxxbxacxaaaxdxxdabbbxxxxaddabbxxdaxxdaxdaxabxxdxcbxddbacxbxbaaccbbdadacccdaacbdbdbcaaaadabbadadbbacaddbaaadbdbadaaacdaadbbdaacdbaacbaaaxxaabaxxaacbbcbcdaadacbacbababadaaadbbaabdaaaaacaabdacaacdbdbcbaaacxxaxxcdxxbaxcdaaxxxbaaaxxxabdxxxdxxaxbxxddbddadabaadbbaccdaaaxbdbxdxxaxxaaacxxaabxbbxxaxbxcacbaxxbxdxbxxxadbdxacxxxxadabxddxabaxdacaadaaacabdacadaaaadbaabadadxxxxxcxddxxaaacbbaaaaaccdbcdbbcbaccabdadaaabdbacdbxxdbcaacbaaacbdbddbdbcadaacadbddabccdxxaxbbacxxdxcdadabaxbadbabbbabcdbadbcdacadbbbabdbadaadabxdbacxbdxaabxaxaxcddbcxxxadacbaxxxbdacdabadbcdbacdbdbabcdbadbaacdadbaaadbaadabbaaddaaabxxdaxacaaaacbaaaaadbaacbbaaaaacdbaacdabadaacbabdxdabdbdxacbxdaaadadxcxaacdaxxcaaaaxcbxxxxxxdaxxacxabdadaacdaadacaaaddaadacacbbcxbxxxadbacbaxbxaaxbxdxbxxdbxdxacdacxxacxxcxxbxdbacabacdbaaaaabaaacxxxbxxxxacaabxaacbcxadxcxxabcxxxcaxbbdxdxbxxcdbcabbaacdaacdadbcabdbaadababdbadbadbcdbacbdbcdbbddacbabadbaaabaxbacadaadababcdbbdbdbxacbdbaddddbdaadababbxxxaxadaxaacxaabdbddadacdadacccxbxxaaxbxbdbacdaaaadabdbbaaabcaaadadabaaadbbddbxcdaccdbdbbaabdbabxaxacaadaaadaaaabdadbdbaabcaacaacbbbdxcxcxadxdaxxdbcadbbxadxbxdbbxbxdbacadacdaacdbbdbbaaacdbadabdbaccdbddbaaaababadaaddaaaabdabadacadacdacxbaadbdbdbdbaaadaaaaabadbacdaxbadxaxbdaaaxaacxaxxbxadaxbxxaxccxaxxacxxxxdacbxaxxbaxxxabxxxbcdxaxdxaaaxbxcbxbdbxaaxadbdadbdbaaddaadbadabdbbaaabacdbxxxacxxadaacaxdbdbdacdabbdaccbaadacaaabaxxxxaxbdaaaadbcdabccbadadbaacccaxaxxdbxxxxxabdbxxdbaxxxxdaxaadxadbxxxaadaxadaxaaxcxxdadabcaaxdddbxaxabaxxbdaaaxxxxaxbaxbcxadbcaadaccdaaacbcacdbbddaacaaaaaabddaabbadbccdbdbabaaaxxaxxbxaaacbadbbxdbxcxaaxxaxababdacxxxbxcxaaxxdxxxdxxxaxcaxxbxaxbaaaxdxacdbbdaaxdbbbxdaaxxcxxcxxdxxxxdxxbcabdbacabdbdaaadbaaaadbbddbbdaddaacbacbadxdacbdbdacxadaxcacddaaxdxxacdaaxxdaacdxxxxxxxbdxcxxbxxxcbxxxxadxcxxdxxxdbdabdxxadabdaacbbaaaabdadbdabxcbdxdxaadbbcaabdbdbabbadaxacbaaaxdxbxxxdbdxxxdababbaddbdadbaacbaaaaacbcxacxxxcacxaxxxbdabacxxbacdaxxbxbdbbdacbacbbabadbacacbaaabaaaadacbdaaddacbaacbaacxxxcxdaaadbdacabaabcddbdaaadbdaabcbaadaxdxdbbacbaaaacbadbcbbbdabdbdacdacbdbcbaddabdxbabadbcxaxdxdaxaxdbacxxxdaadxxbbbxbdbdxbxxxaaxxaabbxacdbaadbdadbadaddbdaacaddxacbxxcddababcbdaadaabcaadacbcbddbxaxadbaaddbxabadxxdadbcbxcdxaaxxbdxxxxdxdxdaxaxxaaaxxddbxaxbcdaaabdaaadadaababdaabbdacaadacdbxabdaxdaabxdaaxxaxddxbxxxxxbdaaddbxxbdaxbxbaxaaacbxcxbdaxxxxxaaadxxbbbxxaxaaxdaaadxbxcaxxdbdaxadaxbxdbbbadxdbaadaacdbaddabacbaacdbdacadacbdbbaaaxxxxaxcxaxxxabdacdxbxbxaxaabbbdbabadbbbcabcbacbbaaaaccbaaccabaaaadacdbdadacabdaxxxdxdxcxbxxaaxxxadbxaaxdbdaacdaaccbdacdabbacacaccaacdbadacdbaxbaaaxbxbbxdxdbcadxdaxaxacabadaaaaabcadadbcdbdaadadxxaaabbdbcbdaaacccabcbdbbxaxabaxxbxxxxadbababcdaabaccbbdaadaxcxaadxxxaxaaxaaaabacbbbdbcabbaddbaabacacxxxadbxbxxaxdabxacxaxxxcxdxacabxaxxxabxxxxdxdaddbxbxadxbcdadbdacabbcabbcdacbbbaacaaxbxaaxcxaxxdaaxdxxdaxxaxbxxaaxbxxccdbxdacxxabacdabxxcdbbxxdxbxxxxaxdabdbxaxxbxaaabxxbxxcdxdxdbdaadxacxxbaaxaaxcxdxabxbaxdaxcdbabdbadaadbabababaaaaaaabbcadxxdxxaxxxdbaxbaaaxaxxdxcxxxcxaxxaaaxaccxxadxxxxxbxdaxxxxxxdbbxbbcxbxxxxcaaxaaacabbbaaabbabbdbaaaaabdbdbdbaxdaaabaaxdadxcbdxxxxcdxxabdxxxdaabxcxbxbbxxxaxxxxxxxxddaxaccxabxxaxdxdxbaxacbaadbxxdbcdxdbxaxaaxdxaaaaaaacbabdxaxdbdaxxxbbcbdxdbxxxxaaxxacxbdbadxaabadaabadaaadaadacddabaaaabbdbcbdabxxxacbaaxxxaxxaxxaaxxdxaaxxababaxxdaxacaaxxacxadaacxbbadbadbaddbcadabaabddbbaxcxdbxcxdxxbbdxxacdxdacaaadadabbdbbbaadbddbadadadbcbdxxbdxacxbxbaabdbxxbadxxaacbaaxacccbabaadbcbaddaaddaxxdbdxcaabdabbbcbadbacdbacbaaxdxxxdxdaxbdxaccxdaxbxaabaxaacaacxaxaxdxaxaaxdaaxaxxbxabadaxxaabdxxxxxaxbbxbxxbdaxcxcdbbxcxxaacxbxaxadaabbadbaaddabbdaaaacbaacbaadaadbdaadbbddbbadadbcbbdaaadaadaaadacdadabxbxxbaaxxadbacbxaxdabaxxxcaxxaadbcaaaccdaaccbcacbaaacbbbacdaadaaxxxxbxxdbxbaxacadxxbdxbbacacbdaaaddaaaaaabdaaacaadbxxbxbbxdxacdbcabbxaacdaxxbdxcdaxacacbbadabbdbaaabbdbbbacbdadacccdaacbacaaaabdbdbaacdaxbxbbxaxaaxxdxxbbxxxxaaxxcbadxxxaxxbacxxbbddabdacaxdbaaxxcbxbxbdbxxaaaxdbxbxxaxdxaxxaxbbaxbcxcdadbxbdbxxxbaxdxxaxbdabacadaaaaaaacdadaadbaaddbbabdaacbxaxcxadxdbxxxxaaxbdxxadxxbbaxaxbxadxbdxbbbabxxbaxaacbbbaaddbddaaaabdbadbdbdxxdaxdxcdbdacbxbaxbaacdabdabaxxcxbdxccaaadbbdbdbaacbdbabbcbaxaxbaxxxxdaxxxbdaxxcxaadxxbaxxdxdbdbxbxdbdaaxxxddbxaaxxxdacbdaaabaaaccdaadbxxxbdxcxxaacxxdabcbbcxdxdbcxxxxdaaxdxaxxcxxccaabbaadbcbbabdbabaaaddadaxdbxxdaxxxadxxdxabdbcadxabdxxaxaacacacadbdbdabadbdaaaccbdbccaabdaxdxdaxbbcadbxbdxaxbadacdaaabbabbabcdacdbbbcbadadbdadbdbddacbcbdbdabddbaddbdacdbdbbabaabdabaddaababxaacxbxxxxxxabbdacaaadbbabaaaaaaaaadbbdbbdadaacdaaabbdaaaaaabbdbbbaxxbbcaadbxabaacbxxxcdbxbbabdxxbxbddxcxbadbxcxdaaabxxxaadbcbaxcxaxbxddbaaxdbaxxxaaxdbabdaxbxdxcxaxcadbdxxxabdacdaadbaabacdacbaaaabdxadaddxxbaacxbabccdbdbdacbdadbbbbbdaadbxxdxxaadaxaxbaaaadabcacdaaacdbabdbaacbabdbdaaaacdbadaccbcbbdabdacaaabacdabbbbdbxxxddaxxxxdbabxbabxxaxxdbxabxaxxaaabcxxdaxxxdbabdbaabdaabdaccbdbdaadxdbxdaaxbaaxaacaxxxbdbxxbxdbaxaxacxxdaxbaxadxxabdxcxaaaxbaxaxabxxxcdxbacaacaacadbdaaadbddbdbaacabadbaaxxadbcbdxbcdaddaxadacbxdaadxxaaaxaxdxaaxxacdabbxbxbabbbdbadbdadddaddacbbaadbbabdaabcdabcbabdaddbdabcxxxxxbdxxxbcdaxxdxxaxxbxabxxdadaxbxaaxbxxbacccdbdxbdbbxdxxxdxdbxxdxxbxxxxdxxcbabcxdxdaxaacxcbxdxadbxxxxbacxaxcxbxcdxaaxxaxaaxaxaxadbadacadabdbaacbaacdadacbcacbdbbcbadxxxaxxcxxabxxxdxxabxaaxdacbxxaaxaxxacxbdbcdxbbdxdabxcadadbabdbacbcdbabcbbababaaadaadaaabccdadadaacbadaacccddabdacadbdacdabbaxxxxdxxxcadbdadxbxaaxabbbdxxababxaxaxxaxxcxxdaxbdacxdxxaaacaxxbcdxbbdbcbdbacadaabaaaadbxdaxxbbadbaxxxbxaxbbxdxdxdbaabdacdaaacbabaddaadacbaabdxxxdbaxbxxbabcxdbadbcadabababdbdadadabcddadbxaxxxxaxxxbaxdbxxxbadadaxaxdbcdbcbxacxxxxaaxcbdadbadbbbcdbabdbdadbaabbadbaaacdbxxxbadxxxxxdbadbaacbaaabccaacdadadaadacaccbaadadbxxxxaabbcdbcaabdacbdbabdaxacabxbdbxxxddxxaxdxbaxaxaxxabdbabbaxaadbxbxbcbxxcxbabxdxadbxabxaxcdxxacdxdbxxaabxxxxaxxaxdbbxxxxddabadabaaaadbdaadbacbcddacdaaaadadacaadbacdacaxacabxbbaadxaxxababaxdaxxcxdxdbdxaxbadbxxaxxxdxxaxdbxxaxxaaaaadabbdbaddacaadacacadaacdbbaacbbdbaaadddaabcaaaadbadabcbxaaxxxadbxxxbabcdadacbaadbbadbaabcbbdabababdbcaadaccacbcxbxaxxddxxaabdaxacaxxacadacbabdaaadbbacdaccbaaaaxxcxadxbxacdabxbacbxxxbbxaxadxaxcxcxxxbxdbdaadbabdaaxaxxdxaaxdaxaaaabadbcacbacdbadabbdxxaaxaddaxdxxaxacbaxbxbaaadbxxaacbbxdabbbabacxaaacdddaadaabaadadaaxxxxbxcabxxxxxaxxxaaaxadxaxxaxbxxxcxdbxxaxxcxxxxacabacdxdxcbaddbdabaacaadaadaccccdbabbdbadadbbaacabaabxbdxxxxbdabcxxaxbxxaxxacxxxxbxaccxbbacbdaabdbdbaddbaabbacdbbbdaaacbdbdbdadbbaadabaaaacbabcadaacbadaadabaaddbaaxdbddxcxaxxxbbdxxxaxxaxxxacbabxxcbbdbbbdaaadbbdadbadbdbbacbaxxxxaxdxbxxdaxbxxxdaxabxxbxaxbdxadbacabaaadbababdbcadadacabdbaxxaxxxcxbxbcbxaaxxdxdxxacaadabxdbaxcxadxxxadxxxbxxxxxcaxdxxdbcadbxaxxaxxbxcaaaaxbcxadxxxaxabaacbdbdbaddadacadacdbdxxaxcaabdbbdaaccbcaabdadbaaaacccdacbdbbacadaaabxdxadbxaabcddbcadbdbbbcdbacaaaadxxbcdaxxxaccccadabbabaadaacbaacxaxdxxxcxaxxbxxaxbbaadbbxdbxxdbaxbaadadbabaxbdabbxaxbaxcxaxabaxbcacdxxdbdbbcadaaacddacabdbbacadacbadaaacaadbacbaabdaadabcaadbbbdbabacbdxxbxxxaaxaxcxdbxbbxbxdaacbxaadacxaaxxaaxabadxbacxaxbxbxxxaxaxcxaxxxbxcbxcdacxacxbaddaxbxbxxaxxxbxadbbdaaxaxxxxabaabaabaacbadadbccadbxdxaxcaacbxabxxbaxdxacdbbaaacadaaaaabacbxxxbxxxxdxxxdbxdddadxbaaxxdbxdxaxbabxxxadadaxxbaabadabadbbadddaccaabaxxxccdxcxdxadxaxxcdxxdbxdbxxadxbdbxabacxdxdaxadaxxxbxbababaacaababdacdbcbacacdbaaaaxxaabdxxxdxaabbcddaadaaadaadbaabcdbcdxaxxabdxxxbabdabdbaadbdbaadbdabxaaxxabxxaaabdaabaaaacdadaaacabababxacbbxcdxaxaxdbabaxaxxxxaaaxdxacadbdxadbabcadbacdbdbaaaaacdaaadaaabbdaacddbcbdababaabdxaxcxdaabdxacbddaaaacaaaacdbdbabbdaccaxbadaxxxxcbbbaxdxdbbxaxadbdbbdbcdacababadaaadbdddbacdaacbdbbdbabbdbaadbaabcacdbaadadbaxxabbdaxxabadbacdbadbbcdacbbcdadabxdaxcxaacaadbaadxbxxaaaxxbdabbaaacbbcbbdaacdxbaadabdacbaaabaacdbdadabxxbbxxadxxxbbxxdxabcxxdbaaxxdbdaaaxbxdbdxbbaacdbaaxabxdxxcabxxxacxxbxxdxxdxaxcbaaabaxbaxabxbxxxaxxadbabacddbaabbadbbbcbacabbaabbabadabcaacbdbbcadaabbacdbbadbbdabbaadxdaxaxxaxbacbxxxbxaxxxxccdbaadacxaacdxxdaxxxcdabbadadbdaaabdbaaaaaadbdaaadbdacbdbcadacdbdaabdbbcaaaadbdacadbacbdbcdabacdacaabaaabbcbdabxxaxxdbdaxbaaxdadadaaaxaaxbbbdadabaaaadbacacdaacbcxaxadacbdbdaabadbaabaadbcadabbdbdabdbbaadbaabbabdbdbbabaababbdbdbabbaadabcxxdxbdbxacbxxaxxbcxcbdbbaadabaabdbdaaabdbdbadxcxxdbaadxxaxaxacxxbxxxbbaaxxaxxaxaabxaaxcdaacbxxxbbxxaxcbbxdbxbxaxaaabddbcaaaadbcaaaaxdaxdbdxaxxxbdxxbaaxxcxbdxaxxaaxxadabxaaaxxaaxxxxxxxcaacxbxxxcxaxxdaxdxxbxaxxxcxcacdbaccdaacbbbaabbdbbdadbaaaxxcbdaabdabadbaaaacacdbadbabdaacdbdaaadbbacaabcadbbxxxxxxxxxxdbcddbxbbxadacdaaadbdxddxxxxaxbxdaxdxaacaadbbabadaaadbcaaaaaabxaxxbaxdbbxaaaadbaxxxbabdaaaxxxaaddxdabxxcabcaabadadbdbdadaaabbaaadabadbdadbaccbdadbdbbdaabbdaadabadbbbabdaccadbdaabdaaaccaddbaxacbxxaaxbbdabaacdadadaadacabacaaaxdbaxxxxaaxaxaxdbdabdadddaaaaaadacdbabdbdaccdxbdaaaaacbbdadacaadaaaadbcbaaabdbbbacbbbcxcaaxdaaaaxdxacbccbbaadbbaadbdadbacbbdacdbacdxxbxxbaacxxxxacxxbcxcxdaxxaaaaxcbabadbxxabdbaacaacdaabaabacbdadadbbbaabdabadabacbacccacbaxbxxdxxaxxxxabdxbxacddacxxdaaxcdxxaccxxcbdbaaabbbdadaacabaaaaaacbdbddababcdaxdaabxcdaadacddbaaabbdadbddaacaaaaaccaxxxbdaadxbaaxbxaxxxxbxaxxbxaabaxxaxxbaxxxaxdxxdabxaaabdbbdabdaababdbacdbdacdadaadbaabxaxxcxaxdbxdabxxdbxadbdabacaacdaaadbbbbaadbxxxdbbxaabaxdaxbxddaadaaxxdxabbaacbaadadbbabbaaaacbdacdadaaadacaaaaaaabdbdaadbacddabaabbdaadbdaabdbxbaabxxcbbxaadaxxcdxaadxdxxcxddbaabdbcdbbadaadaacacaxdabxxxxxxaabcbabadbacbddbdbbabaaxxxdbxddbbabbdbabaabdbbdbaaadacdabaabcbdbadadbadbabdaacbbbaaabdbadabbxxxxadaxbddbcacdacbabbdaaadabcabaaabbdadadabaacbacdacaacdaabcacbddacaaacdabaaaaacaaadacabcxbxbxacdacxxbaxaxxadxxaadaaccdbdaabadbabcbadxxxxxxxxaxcadxaabxdxaxxbabdadbadacbabbaabacdacbdaaacdbdaaabdaaaadbbadbbdbbdacbdabddbaaacdabaaadbadbdaadbabadabcbdacadadacbaacbdbaaaadbabaaadbaadxxdaxxdxdbbdaxxdaaxacxxaacdxaabxxxdxabxdxcaxxxcbdbxxbxxacdadbbaacdabcbccdbccdbabcaaaacdaaaabxddbaacbdbdbdadaacaaaccdabdbaaaxxxbbdbxxxxxdxcabacdbcdacaabbadacdbdbacbdxaaxadbdbbbabdaccbdbbcbadbcbbaaaacdacdaddbcababacdabxaabxadbaaadaaccacdbcdaaccdbaadaaabcdaaaadacbdadaacadaabdbaaabdbdbcdaadbdbxxadxaxxxbaxaxxxaxcbbxabxbdadbbdaadxdxaxbdxxbxxxxaxxadxdbdacdaaxdacbdbdadbaabdaaacabdbdbacdacdaaadaaadaaaaabadaabddacdxdaabxcbbxdbxxaxbxxxxacdxdxxdxxdxxaxdadaacbxxcbxdbbcxadxaxxxxcdxbxxaaaxxbxxbaxdadbxbbadxdxadaabaxcaxbxxaxabaxxcxaaxdxxxbdxdxxxaxdxbxxxbdxaxxxdaxabdacxbaxabdxaaxxadxdxacddbacbcacabaddaadbabaaaaaacbacdadbabacbababbaadaaacaadbacaacadaacaxxbbxxaxaaxxbcaxaaaacbcadbdadaccadbbacabbaacxaccadxxbxaabaacxxbaacdbdaabbabxcaxxaacaxaxxaxbdbdbbaxxaabaacxbaxacxaaaxxxcbxdxxxaxbdxdaaxdbaxxxbaccbcababcaaacbbacadbaadadaxcbddabddxaaxdbcxxbadaaxaacaxbabacxxxdbacxaddxcxabaddacabaaabaaaaxxcaacbxbxdxabxxbcbaxcbaxbaxxxxabxbadxxbxxxxdxxaxdaadxaxxxdacxbxadxaaxdabcxaxxaacxbdxaxbbaxxaaacadbxaxcddddaaaaabbabbdbaaaddadxdxcxxcxcxaadaddbxaxbxbadaxbdxxccbbaabaacdaabdaadbcdbddxbxdxxaacxaacxxbaxxxxdbxbbcxxaxbxxxxcababdbdadbdbaaaaaaaacaaaacbdbdaccbdbcdadabdbbbabdaaccbcdacbdadbcaxxxacaaddbdaaxacdxacdbxxxacxxcxbadabxbddbdxbbacxdaxxxacbbdbdabdadaacabacabbxxbabaaaccxaadxbccxbcccdaddaaxxacxdaaxadadbdaaacdbdacaaaaaabcaacaacbcdadacabaxbxxbaxxxbxxxbacdaacdaabadbdabdadadbcadxxdxxxabcbaxxxxxbaxxaaaacxcaxbaaxxaaaxxbdbdaadabaxdbaxbxbdacdbababdaacbaabacbdbbbdbddaabbadabaabcdadbaaxxxxcxaaaadaaaxadadbdxxxxdaaxxadaabaaacdbdabdbdacadaabbxdxaxacbxxdxxbaabxxxxdxaacxaxbaaaxxdabxdaxxxbxabdxxdxacbaabdbdaaaddaaaabdbaabddadbdxbaadbxbxxbdxxxdbdbxdacdbddaaaadbacbbcabdaadacbbdbcdxxbdbaaddabbaacdadacbdbbxxxbdxbbdaxxcbbxdxacdxxadbdxxxxdaaaaaaadaxxbxaabxxxxbdxxdxacxxaxacxxcdxxxbaxxdbdbdxbcxcaxxxadaxxxaxxxxbcdxcdacaxxadbaacdxdxxxdxaaacdaaaxacbxaxaxxxadxaxcdxxxdbxbxadadxacxbxxddadbbaxxbaaxbxaxbadbaaaxacxabxbaxaacdaaabxxxxccxdabacaxxdaabacbdaabaacdbbbdabbdaxxxxcacaxxaxxxxaxaxaaabaabacbdaabdacabdaadaxxaaxadaxacdxddxbxbxacdabaabacbbdbaabacdbbdbxxxxcxxxacxbxadxaxxaxcbxdxxxxbdaxdbabadxdxacxbaxdxacaaxaacxaxaacxaaxxxcxaxxaaxaxdbxxaabdaxddbxxdaaaxxadaadbdaadbaddbdacbdacdaaaccaaabadaxxcxxdbxaaacaaabcbbdbdbdddbbdacdadbaabbaacacdbababbbxccbdbdacdaadbadbaddacaacbdxxdaabxbcdabxxxbdbdabaxabxcaxaxxdabaadxaaaxbdbbdbdbcbdbbdbabcdbaddacacaaaaxbbxxxaxxaccdxbxabbbbacbxabxcdxbxaadbabcxcaaxxaxxbbxbxxxbadaacxxdaxdxaaxabxxxbaxaaxaxxxcxacxxxbxcbxxadxxbdxadbxaxdbxxxdxaxaxbdbbbabadbdbacaadaaacaababcdaaacbaabddbacaacdbbacadbdacccabbacxxdxxbbxxdaccaxdxaxcaxdaxacxaaxbcdaadxdxabxxxbxcdaxcaaxaacbacxabbxaaxxxxbaxxbxbxaxxxdaxxbxaxaxcdxxxaacdacdxxxaaabbdxacxdbxadxxcaxadbdxaxdbbbaabdaaabbdadbaabbdaaadacdaadadaaababbaabdaaacbabbabcxaacdbbcbdxaxxxxadxaxxxcxaxxxdbaxxcbxxxbaxxacxxcbdbaxbxaabaxcxxbxxxaxddxaxabcxxxxaaxdxaxdadaaxabdaxbxdaabxxaaadabaxdbadaxaxxxacbxdacbbdacdaabadadbbcadbdbacdbacdacdbbadadabbabaacdaaxacbxbxcxaxdxxxxxxbxxadbxadadbbaaacbdaadaabddbaadadxaaxbdxdxxdxaxaxbbaxbbaxxdacdxcdxxcxadxccdaaddaaaaabdacaaaddbabdabcxxabbaxaxaxaxxaxaxdddaaaaacbacdbdabdbbaaaaabbabcdacaadbaaadbaxdaxaxxadbxaxdadxcccbacxxaacaaadxadbcaaxxdxxdxxcxaxbdaxxcbbaaxxdxcddxxaacdaxaxaxaxxabdabaaacbaaabadbdbaacabadbaxdaadxxaaadbdbxxaxdaxbxcxbxxxbxaaaxaaaxxabacdadaaacbcdabaaacbbaxbacbdacbdaabddbabdaaxxbaabadabdabcabbadaacacbdbdabdbdabcbbbabdbbdaaabaadxxaacbbdbbabdbdbdddaxxxbabcaabadxbdbabcbbcbbbaaaaaacddadbaaaacxaxxxbabxxxcxdbxxadxxxdabbdxaccdbxcxbxcbxbaxxcxxxdxacxccacxadbxxcxxbaacbxxxaxaxdxaxaxxaxbxaxddxaxxxxxbxxbabbbbbacdadbaabbcdbbaaaabaabxxdabbxaaxcxxaadxxxddbaadaaacaaabaxacxbxabcbdadbdaccdbadadbbadaxxxabxdbaxdxxaaxaacxabdaxbaaabxxabaxbxdxdbdxxxxbbdabdaaacdaadbdbabacabbacaadbdacaacdaacbccdaacbadadbcbaadbaabdacdaadbacaacbxxxxxbxacbxbaabxaxacxxaaxxxaxdbxcbxaaaaxbaaaxxxadbabaxddxcxxxcbbxacaxacadbaxxacxxacxaacbaadbabdaacaabdddbaacaxcbdaxbabxacxxbacadxxxxdbdxxbcbdbaadbacadacbadacbxxabxaaxxxbxaxdaxxacdbaxxxxccbbaabaadaaaabaadbbadaabaxxdbdbbbbdbabbbdbdaaaadaadbdaddadaddbdbddbaadacbdaacaadaaddbadbdbdbababcacdbabxxdabxxdacbaaacbaadbdbddbaaccxxcxxacxbxacdxbxaacxbaacxbbxbaxacbdbaacbacbbdbbadaacacacaaabdabdbaacaacaaaxbxxxxxdadabdaacabbdacdaaabdadaaaadbbdaaccdbxbxxbaxaxcxxbabcaaaxdxbbxbaaaacbacaadacaaaadbaadacacdaabxxccaxxxbxacdxxaxbbxdbaabacxaaxxdadbaxbxbxxxbaaxaxbxxxbxaaxxxxxbdacdbdacbadbbbcdbbacbabadbdbdaccaaaacdadbdaddababaaxdbbbdbcxdaaaaxxaxxxdbxxdxbaxxdaadxxdaxabxxdxxxdbxbaxxbcbaaxdbxdbxxxxxadbdbaxbxaxxbbxxadbxacdxxabdbcdabdddacdadbaaccdbacdaacaabaaaacaabdaxaacacbxcbdbbdxdbbccaadacdadbaacbdaxabdaxxxadxdaaxxaxbxdaxbbxaxxaxadabbbdxdaxaxbxaxdbxbbaaxxddxaxdbxxabdbcdxbxbdxxxbbbbacdbcacbbddacaaaababdxxxdaabbbaaacdaaddadbdbaababbdbxxabxbdaxdacaxxaxaaxxaaxxbabccdaabacbdabbbaabaadaabcxbacxaxxxxxxabxxacxxbddbxbbaaxxxaaaxxbaxxdaxacacdbbadbbadaddbadadbdabdbaaabbcbdadbabadacaadacadaddxaxadbxaaaaabaacbddaxbxdbddxxdxxbxaxxxcaxbxxbxaxaadaacdababadaababdbdaaxxddbcbxcdxaaaxxxxaxxcdxadadddaxxbxddaxxbadaxxdbdxbaxxdxadaaxaaaadbcdaabbaaaaacbddbbcaacdbbddbaxxxxaxdbacxdxdaaacxbdacddbadaaddacabaacadbaaacbaadbaadxaxaaxcxbbxabbaaddadbbdadbabdaadbacdadaaddbdaabbaabadbdbaacbbcbaadbdacdaacaaaadaxcxaaaacxcxdxacxaaxdbaacdadaxcxaxadaadxaxdxxbxbaxcbbdaxxbxadbxxbdxcaxbddaadbdaxxbadxbaxcbxxaadbbcxxxdaaxaaxxddadaaaaddbdaaaddbaadaacxxxabdxdxaabxbdacxxxxdxxadabdadbbdabdbcbdbbaccbcbadbdbacbaacdbdabbaaaccbadadbadbddabxbxxdaaxaxxxabbbaabxadbaxaxxadaxxadbabxxxaxxxacdxxaabbbdacbcbacaadacbdbcacbacaaaaaxacxxbdxaxxbxdacbxbdaaxxdabbcdabacbddabaacaadbaaabdabxxxxaxxdbxdaxaxbaxacxxcxxaxdxxbxbcdxaxdxxaaxbxadabxadaxdbdxbaxxbxadxcxaxbxabdxxxxacabxxbxbdxcxdxadacaxxxcbbaxabxdaacxxaadxaxaaabaccxabdxxacbdbdbxbaxxaaxabxxacaxcxdxbaxbxbadaxaaxbxxbbxbcxaaxaaaaaadbdbcbdacbbbbaabdbdaabxaxaxacacbxcbbaacbaaaabbbcacaacbaadaababbaadacbdbdbdabbdbbdbxxacaabxxxxbdxdbdbdbaabdabdaaaaccacdbbdbacdaabadabdaacbaaddxdaxadaaxdxxxdaadxaxcbcbaaxaaabxaaxxcxbdbdxxbdbcaadaxxxxbacbxxxxaacadbaxbxdbxaacxddbaacbcaaacbdaadbbacbdaaddbbdabbbdaabaabaaabdadabaaacaddacdaacdadbaxdacdaxaxdxaaabdaaaaadabdaabbdabcdadabdacdbxbxadxabdaxxxcdaaxdxdxxxaxbxaxxbcaaxcxxcxbaxxxaxxxacdxxabxxxaaaxdxbbadxbcxadxbxabdbaaxaxxaxbcbbbadbacbcdabaaaaaaacaadacbadbaababaadbdbdbdacacbbbxxxdaxbdaaaadbaabcbdabdadbacaddbacaxaaxdxaccxdabacdbbaccbdbdbdbdbdadbdaadbbbaabbdbdxxbxxcxxdadacbdbaadxxaxadxaadxaxcxacdaaaacxababcaxxxxdxcbaxadadxxxxxxaaxadaxdxacdaxabxxdacdbdaaadabbaaacaaadabbbcabdabaaaaaaaaacdbbdbaacbdbdabdabaaaadbdacbadaadacadbxxxxaxacxxdxbbaaxxaaacaaaabxbbaxdbxxadxaaxdxxaxxaxxcbaxdbxdaaadacabxxxaxadadbxxxxxdxxcxxxxaxdadaxcxxdaaxcbxaaxbdacccadbdbaaaabbdbaacbbcbdabbaadbcdadbbddbaacbaxabacxdxxaxbaaadxbabxaxaxxdxbbaxadadaaabaaadbbcabaabacbadaacdbbaxxxxaxaaabxdxdxabaaxcxbbxaxaxcadxaxbbxdxbxaxbxxbxdxaxxdacbxdxbacddaaabbadbdbdaaaacababdadacdaabbddacadaaabdaaaxcbxxxdbdaaacabaaabbdbbdbaxaxacddacbdbabacdabbadbacbcdacbbcdabdadbaaacadadabbbaabbcxbxbaadabxddbaxxaxaaxcxxxaxdaacdbxxdxxdaaaacbaacxxccxxaabdbabdabcdaaaadbbdbdbbdbcaaadbcdbcdacdbdadaacdbbbbdbbxaaxaaxaaxaxbaxacbxaaxxaacxxbbaaabdbxadxxdbxxaxxxadxdxxbdbaaabdaadacaaaddadbxadaacccabbdadaaadbdaaaxacddxaaacbxxxabxaadaacdaaaacccbbaaaadaabaadaacbaabbadadbbdaacdbabdbdabaabddabacdaaabdababbbcaaabdabbdaabbdaabaacaaaabbdbddaadabbbxxbxaaxcxxdxabadbdxcxdaxbdxxbbadxxbbxcacxxaadbbxxadbxabbxxddxbxdxbaxabxaxbbdxbaxacxabxaaaaccaabbacaaabbdxxxbdacbxxbxbaaaaaaadaxadaxabxadxxacaaaxdbxaaxaxxxxabcacdabadbbdabaaadbdaccabbxdbxbbdadbdabcdbdacdbdaadacdxaaxxaxxbxbdxaxaddaxaxbbxxxxbdxxaaaxbdabdacbbbaabbdadbacbabbabdacbbabdadbbacaddbbbadxabadbxxxxxxaaxxxabaaxadaadbxaaxxxxdabxxxxxaxbxacbaabxxxcdbbxxbdxaaaaaxxxbaxbdxaaxxbbaxxdbaxbaxdxdaxxacdaaacdbacdddaaadaadaadbbaabbadaabdbbaxxcxbbaaxaxxabdxxaaxbxxdbaaxxbxadaxbxaxxbxaxxaaacxbbcaxxxxxxbbaxadbadbdbcabdbdbcbcdbbcababcbcbbbbdbbadbbaxxxdaadbxbxxaabcbdxcbxxbxbcaddbaxxcbxaxxacbcaabxxbcbbaaacdaaadadaccadbcabdbcacbacbacaacbdadbdadbacdaaadbdaxbaxbdbxdxacaacbaaadxxxacabbcdbcadbccaaaaaadbabacbcdacacdbabdabacabaacaadabbadbaccacdbaddaacadaaacdbcxaaxaxaxxdxaxdxbaxxxxacxdaxxxdxxxdxaadaxxxaccbbadbddaaadbddddabdbdaaaacbbdabcbaababaaddabaaaabaaabbbadbdacdabaaaacdbcbbadacbxaxcaxdaadbdbadacababdbdaabxccaxxbcxxcaxdacxdbbdxaxxacdbaadbdaabaadabaaaaababbadaaxxxdxaxcbaacccddababdbdbabdbacdbadaaaaaaadbccaaaacxcxaxabxdbxcdxaxdacdbadacxdxxadbabxbaxabxxaaxdxxaxaxbaadxaaxcxcbdaxbdbaxddbxabbdbadbaadacdabdabdbbaadbdaacbaabbadbaabdbdddabadabxxxdxxdxcaxaxbxxaabxaxaaxxbbxxcbxcxxadxxxaxdbxxxxxaxdaaddxdxxadbcbadabdaaacbacabdxxxxaxxbdbxabaxxdaabbxbcacbabxxxacabxxxdaaaacbacdaabccddabdadbdabdbbdaaaxxaaaacbdaabcbabdadadbadbaacbxxbbabxcxxxxxxxbdaabaaccbabaacdbbabadadbaaacdaadxdaxbbadbadacdaddaacbaababbaddaaabacdabdbcbbbbdacaadbaadabbaabbbaddxbxabxxxxxxaxbxaxxdacxxaaxaaacxxdaxxxxxbdxaccaabdaaaccxaxdxbaabaxabxcxxcxxxacxaxbbbadxaxxbxbxdaaxcdxdaxbxbaxdaabxxadxaxxxaaxxabdxcabaxdbxbxbxdaacaabcxxxxaxdacxxaaadadaddbacddaadbcdadabaabxaaadbaaaxadxxaccxxaaxcxaxcxaaxaccdxxdaxxaacxxaaaadadbddbbaaddbabaaaadbabxaaxxaaxaabcaxaaaxaxxbaadacdaacdaadbacbaacxdaabxbxbbaxadbabcaxbxdabxaababxcxxcxacdadadxaxxxdxcadxbdaxxaxxcadaaxxxacxxxdabxxacaaabacbxxacxdacxbbbaxdxxxxxxcbbxxaaxdacxbaxdbxdaacdacaacaaaabadadacdbaccaabbdaadaabadbacdacabccbcbcaacbxxxxxdbxaxaxdxxxaacabaxaacxbxxdxcxabaabdbaaaaabcddbcadadaacdadaaacbaaxxxxaaxacacacddbadababbabdabadadbdabxxxcxaxbxxxcxbbxabxxaaxdxaxbxdacdabbadacdbbabacbxaxxdaxaxxabaxxdbdadadacaabbaadbacbdbaaxcxbbxcadbbxxxaxxxaaaxaaxxxacbacbdaaadbbxdacxxbbadxcdbxxxxdaxxbbdbxaaxdxabaaaxbxxaxbaxaxacdaaaaaacbbbacccbadacadadbbdaaaaaabadbacabdacbadbcabadbadbxxcxxxaaaxxxaaxbbxxacaxcxxbxdadxaaxxbaaacbadaxadbdbxabcadbabbdbbdaaddadbaabaadabdaabddacbxxxaaxxxxdaxxxdbxxacdxadaccdbbdbdddaaaababaxdbxxaaxbxxcdxbbdaxaadxbababaxxxxxxdbxxxxbacdaabaxxbdbbaddbabdadbcdbabaaabadaabbbadbbdxdacddabaxdaxxxadxbxacaaacbdbaaadacdadbabxbxacaxdbcxaxxxxadbxxxxxaaxbaxaxbxbabbbxxbxbxadxxxxaaxbaxxxaxbxxcbxaabxxaxdaacxxaadbbaaxadaxacaxcdxdaxbxaxcbxdabaaxxxbabdbbdxcdacxabadaaxaaxxxxxxaxxxcxaabxacxxbbxxaaxxdxxdaxaabacaacdaaxxbxxbcxbaxaxxxdaaxxcaaxxxacabxaaxaxcxdxdadbdbxxxaacxxxbxbdaxxaaxdaxdbaadaaabcdbcdaaaabadaaaacdabdacaxxaxadaxaxcxaxxbacbbdaaaaadbacbaaccacbbdacacdbdaaadbbbxbdxdxbbxxxxxabaxxcxcxxcbbcdaxacaxxxxaxbdxadbxcdacdabxxbbaxabbaabcxdbaaxdbaadxabbaaxxadaxbdabcxaxaxdxxdxaaxxacaxdbaxbadadxabacabbacbbaacdaaccbbbacdbdaxaxbaxcxxaabbaxccbaaaaaaabdaaxbbdxdxaaxdaxaxbdbxxdbaaaxxcaxcabxacbdadaabxabbadaxbaaadbxbxaacxxacbbcbcbadbabbbaacacbcbdbbbaxbaxxxaaxdaadaxbbxxdaxcxbaaabxdaxcxaacxbxaaaxaxxaccaadbdbadbdabadadbbadabaacadabcbcxbxaxxxbaxxxxddbxbxxxdabaabdxbdxxxxxddddaabbdbddacbaaaaacdadaacbdbbaabbxxaxxaxxxaaaxdbxdbbxcbxaxcdxabaaadbxdxxcxxxaxdbaabxxxdxdxdxaxxxabaaxxxadbxadxadxxddxcxddxaxbxcxadxbdaaaxxbxdxxaxaxacxcaaaxbxadaxxbdxdacxcxdacabdxaxxxbxxdxxaxxxdadaaxcdaaaxxbabadaaadbbdbaaacbaadaaadbbcdadadaaaacbbaaabbababaabbbdbbacadbdacbabbbaaaabcdaabadbacaadxxaxxaaxbbdaxxdaxbdxbdaxcxaaaxbxdadaaadacdabadbdbaabbaabacbdadbcdabbaacbdbaxaaabxxxcxcbbxdxxaxdxaxbaaxxdbxadxadadbxxxacdacdaadxaaxxdacaabdacaacbaacbabadbaabbdacbxacxaxxxxbxdxaxbdxbaaxdbaaxacacadaxdaxbdxbxacxxbxaxdbxaaadabaaaxxxxxaxxcxxbxdabbdxxxbacdaccaaadbcaababcacacdacbaababddaadbdaacxbaxbadxcxdaaxbaabcxbaddbaxddaabacbacbbaabbdaaaacaxaxdxaxxxxxdbcbaxxxxccxxxbbxabaxxdbdaaacbabaaccdadadacaadbaacxxaacxcabaaaaacdbdbbcadaacdbcxcadaxbdxdxdxacxxaxdaxaacbaxcxxbxabadbaxdbxxxxaxaxcxcaxxaxaddxxbadacaaaaccaadbdbbadaxxcdxxxaaxxdbxxaacxbxxbxbxxxxxaaxxbbxdbbaadbbxbdbabdacabaacabbdaaacdxxdxcacxxaaxaxdxabdaxxcxabdaaababaaadacxaxxbxaaxxbxcxabxadbdaabxxdaxadabaadaaabcbdaaabaxaaxaxbxdbxxaabaaxxacbxxacdbxaxxaadxxacbbxxaxaaabxxdbxaaaxddbaabbdbacababdacacbbaadxdbabacxadaadxaaadaxxxaaaxxadxxacacdaaaaaacbdabbadbxxdxacbbxdabbadbcxacxbaadxxaxdxxaxbdaacbdacbdbdababddaadbaadbddaxxdxdbbdbxdbbxxaxbxxxxdbdxbxxdadxxbxxaxcdbaacxbabxbxxxbbxxadbxcbaacxaddaxxxxxaccbcxxxxxxxbaxxcxxxdaaaaxxdxcbdxaadxxxxxbaxdxxxcaxbxbabaxxxbxabxdbxxbaccbaxbcbdxxbbdbadaadabacdbacdabddaacdbdacbabbaxdbbxcbcdaxdxdaxxxdbbaxabxbacxxdbaaaaaaxxaxxabbxcdbaxxadaxdaccxbxxxdaxdaxdbcaaacdadacaacaaacbbdbaxxxaxbdxxcdbcaxxdxaxxdacdxxxxxacbxxbcdbbababbaadabbacbabbaabbdbacaacbxaxxxbacacbdbcabaadbdbcdbaxdbxdxbxxcxaxxbadaxcxabxdaadxaxccxxxxxbxxbxxdaxdadaacdxabdxxxxaabaadaaxbaxxaxaxdbaxcaxbaaaxdbxbxxxdaxaddabbdaaadbaabaaabadbabddxabdaxcdabdxddacddbxaxxaacdadbaabaacbaaaaabxdbaxxxbdbdaaxxxdxxbxxdxxbbacbcbacdbabdbabdbaabadaadbaaaaddadbbbdaaadaacbbbddbcabcabxcaxdxddabbcadabaacbbabdbbdbcbbaxxcaxaxxdxxbbdxxxdabbabxaacxadbdaxadxxdaxxaxabbbccacdbcdbdaadabdbabbdabbabacdbaadxadbbxdaxcaaaxaaaaadaaabadbdbaabbdaaaacaaadabdacaacadbbaxdacadxbcdaadxaaxxcdxxaaxxbxdaxxabdxxbxacxbbxxcbxaxxxacaxxacxdxxxdacxdbaadxaxxcaacabdbdaacdabacdacaxdbdbxxaaaxcddbxaxdaaxxabxxdaadadbxbdxxbbdbxxaaacbbdddaadbadbaaccbacbxxxxxbcdadxxxxbdabxxaxdaxdbdbdaxacacbdacdaaabddbdabdbdxxxaxbdadxxxxaxxaxdxxccxdaxxbadxxcddxdbaabcdbaacddbaadaxbxcxxbaddxxacxxcbxxxdadbbadbdacbdbdbbbaaacaaaaxaaxaxcxbbxxadaxxaaxxdbxxddxdadxaxbcxbdaaccadadacddaadaccbabbdaacbdacdaaxbaxdxcbxxxxbxbdbbaxbaxxaddadbaacbdadabbabaaaxcdaabdddbbaaaadaaadadbabcdaaaccacxbbdxxdxbxbbacdacbabaababdbbadbabadadxbxbxaxcbbdadbbcaxaxaaxxbbacxacdaabaaabcdaabdacadaaaccdaddbbdbbdbbccdadaaddaacbadacxxcxaxcxadaaacdacdacbabaababadaaaxcxdbbdaccaadaaaabbdbadaaaaaadbdbcbadbdabcadacbbdbbddaaacaaadabbbdbbcdaadadddbaadxaxxaaxxxbaxbdacbaaadbdbdacdabcbxxxxbxbaxdxdadxaxdabaxxxcxbdxxdbdxxxaxbxaxxaxdbbxaaaxaxxbdxxbxcxxbaaaxadaxdbxbaxbcxacbxdxxbbdxbaddbadaacdbaaacdbacbaacadxxdbxaxadxcadxbbdxaacxabdxxxxaxdaadabxdxxdbbabcbdaaadaaadabdaxaaxxdaaxxxaxaxxabbxabxaxxxdxdxaxcxxxbxbxbbdxxaacbaaadadbabaaacacacaaabdbdaaaaabdbaababddbabaacaadbdadabbadbbbdbxaxdaxxaxdbxbbaxxxxbdbxabxdxxacxabaxxdacxadbcaxxaxcbbabdxbxaadaddxxcxcbxxaxbdxaadbdaadaaaaabdbcdbacdbdbacdbbadbadbaaxaxdxxdbxabxacaaxdxdaddbbdbadabaaacdabacdbdbdbaadadbdbdaabxaabaccadaaaadbaaacbbadbdbdbadacdacbdaaaaaacbacdbbacdaddbcdabdaaaaacbcbaabcaxbaabaxbxbxdbxxxaxcadaxxaabaxbxxbdbadabdadbabdadbcaxcdaxxbccaxbdaxbaaxxbdbbdbdbdacbdbdbdacbaaxcaxxbabacdaadaacabdbabbdbdbaabxbxxbbdbdaaabacbcbaaabbbbdacacbdadacdbxxdxaaxaacaadbadxxxaxaxaxdxaaaxxbxxxdxxcabcxbdaxbxbxxbbbaaxabaxbxbxdbaxadbbxacbxaxxxaxxbdxxxxxaxxcdbxxdaadxxxbxdxxadadaadaacaacbbaaccabadaabbaccbacbdxabbxxxxaxaxbaxbbddaaxbddxcxddaxxaxbdaxxaxxdxdbabbxxaxdaaxxabaxcxxaxaxcbxdacdaxxbxbbxxxdxdxdbxddaaaadadxxxdxaxadbxbbdacadaadacbbbcbdaaddaadacadadbdaacxxaxbcxacxbdxcaaxcdxdxdaaaxxdbxaxbxaaacbbddxbdabddbacdbdadacbabdbddabcbbdbacaaxcxxbaxxxaxxacacdaabdadbdbaacbacccdbabbxcbdxxbxxdbdxxaxxcxbdxcbdxxdxxxacxxcxxbdacabacbacbdbbdbadbbadaaacccdabdacabaacdaxcaxbbaadxabbxxaxdxdaxxxxxbxxaadbxxxaxdbxxxcbaxxacdxaxxdaxcxxxcdbxbxadbdabxbxxxabacbxxaxbxxcxxxadxdbaxaaxdbxacxdbdbdbxbaxabdxbacdbxaacxacxxxxxbxxxadxaaacbaabdaddbbdaaacaaadacdxxxaadaadaaadaabdaaadabadaxaaadaxxxbaaaxxcbxaabxxxaaaabaxxacxdaabbxxcdbcaxxcbdaacbdxxdbadabxbcaxbxaxcadxxbbbxaxaxxadxaaxxaxaxaxxxabbaxcacxxcxxdaadxaxaabcxdxxdbbxxacadbdxbbdxacxbxxaaaxacxdaxxccdacdbbdadacdbbccdaacbacdbaadbdababdbxbadxcxabaaacxadbacxacxxxabbxaxxxxdaxacxxxxbddxdxbaxxdaacdxaaxaxbaaaacacadaacdabadacbaabdacbaxxxaxxdaaxxbaaxbxbaaxadbdaxxxaxacadaacddxdadadxaxabxcaadacdbxxcxbxaaaxbxabbbaxxdaxbxaxxbbdbadaaabdbaacdadadaacacadaaaacdaaaadaadabbbaadaacdadadacaxadbbabcxcbaxaxaxxbdaxadxbabbxxacadbacacdbccdbcdbddddxxdxxabdbcxdxaadxcaxbbxbaaxxxabcdbdbbcadadbbbdbbdaacxxccdxadxaaabxxbbxxdaxacabxcxaxxdbdbdbxaaxacdaadbxxdxbaxxxddaabdxxxxxxaacacaxaxxxdbdxxxcxaxcxxaxxxbbaxbdbbaacacbacadacddabbdadbdadxababbbdaacbacddbdaaaaxxbaaaxabaxxxxxxbaxxaxxdadbxaaaxxacxdacxabxbaxbabaaxxxxacxcbxxaxxdxxaacxbxcdbxxxxxbxbdxaxxbxxbdxaxxxbbbxxxabxdxxbxxbxacxxaaxaxcxaaxabdbaadacbdaadbbadadbdaaabacdbbadbabcdabbbdxxaxabdxaxaaxxcxxaxxxxaxxxbdabxabdbbaxxbacadabadaccaaaadaadbdbacdaacxdbbcaaacbdbadacdaadabdxbcbcbbdbacadxaxxxbxaxadabddbbddbbacbbcababababbadbacbacbbdacadbcdbcxxxaaxxxxxcaxaacbdxxbabdxbaxxdxxacxdxbxdadxxbdbadbaxxxbbabacdbbacababcdacaaacacabdacdabbxxxaaxxaabcaxxxxadaxaxbxdbxxacxxxaaacxxbddxxdxaxadacxbaabddxxxacadxacdxxxbaxbaabdxxxxdbbbaacabaaaadabdaacxbxxaaxaaxbdaxxadaxbaxdadxxcbbxaxdaaxxccbacdbaaacabbbadacbaddaabdabbbdaacaaacdadbdaacacdxbcxdbdbxxaxcaxcxxbxcdxxdbxbxbadxxxdbdbaabdacdaabdaadaaaabaacbabaadaxadaaaadabcbdbaddaaddbbdaabadabbbadbbdbbadadxaxcdxcdadaaxbxacbdabdaaaabdadaadbdacdacabaadadaaxbxbbdxdxbcaccacxxadadbaaaaxxxadbbxxbbaxdxxxaaacxxabxaacaadabcbxxcaxadadbaxbcabaxxbdxxbdxbaaxddaaabxxxxaaxbxbxbbxcaxabdadabaaddaadacccacdabdbaddaadaabddadacbaadabcdbxbxdxxbxbxxxaxabadaaadbdbbacbdbdbbdacbbdaacbadbdbcbcbcbdaadabbdaadbaccaabaadxxdbccaaabaaaadaaabaxacxxaaxxxaxbbaxaxabaxbaaxacxxbaxxbdxcbcxxxacxbxxaxaxxxxdbdxxbcxbdadaacaaaaabxaxxbaxxaaxbxabxbxdaabxaxxaxxbxaxaaxxaaxxdxdbddbcaabbbacababddaacacdaadxbdxbxxaxxxxxxdbadaadddddbbdacaaaddbadabbacbcbadaaddaxbxxabxaaxxxaxbaxdaxbaxadxxaxxbbaaddbxaacbaxcxbxdaxxabddxdacbacddbbbadadbaadabxxxbdxcccdbbddbdbaadacdbbacddbdxabdxxxxxxbxbbbdacbddaabdbadbdbaaacdaaabbbabaaaaxdbxbddxxxbxaacaxbaxxxxaxxxxxadxcddxbxxccxaacxbxaxxdxadbbdbdxcxxxabxabacxadbxadadaxdxbacdxxxxbdxabxbdxdxxcadbxxdxadbdxbcbaddaabcbbdaabaacdxdaxabdbbxaxdbxadxbxbddbbxxxbaaxxxxaaaxbaacbxaxdxxdxbacaadaacbacabaccddaaacabdadabbdbdabbbdbaadbdadacaabaacdbadaddaabbdbaxaxxaxdbaxxaaxxdxxxddbxbxbcbbxacxaxaxcxbdxbxaxdxcdbdacbcbcdaabaaacdaacdadacabcbaddbdabdbaaabbaaaaxxxbxaxxbxcxbxddxaxaaxxxaaxadbadaxxxbabdbxxbbdacacdaaaababaaaaadaddxacxadbaxaaxabxaxxxxbxxbbaxxdxxxxaxxxaaabcdbbbcacbdadbadbdacxdxdaaaaxxxdaxxacdxdxbaxxxbdxxxdxxbccxdaxxxbxabxbdxdbbxxxabaabdaabdabacbdbaacbbdbdaaadabcdabdbdbbabaabcxdbadxaxabcbcaadadaaadabdbcbaabaxaaxxbabadbxacdbxaaadbbbaacadbadbaabaaaaadacbaacaaabbcbadaaaaaxbaaaxxbxdxbbaaxbxxaacaxdaxxxddxxxbxbdxaaaacdaxabxxbxdbadbbabbcdadbcacaaabdaacbaacdbbbabddaaacdacbcdaccabadbcccadbdacbbbacbadbbaadababdaaaacadxxabxxxdaxxbdxxbaxxxaaadbbdaaaaabaxbxxdaxbabxaxxabdxaaxxdaccadbdbdacbbabbcacadabcaxaxbddbadacdaaadaaabaaaadaxcxcxxxxadxaadbdxaabaaaacaaaadaacdbbbcbdacabcaaaacbdbabacaaadbbbbbdxxaaaacbdbaacdbbbabddbcbaaadaacdadadaacadadadabacdbdbadabbabaadbababbbadbbdadaadadbabxxxaxdxbxaadxxdbadaacaaadbacdabaabdaccaacbdxbaxadxbxxaaadxbxcxbxbbxbbxaxbxxccaaxxdaxbxxadxdxbbdbdxaxbadaxxdxaxxaxbxxaxaaaaacbxxaxddbdxaabdbxdbaaaacdabaaaddabaacdaaaaadaaaccbaaxxcaxaadxxaadxdxddbaxabdbdacdadxxxbxdxbcaxaxdbaaxaaxadxdaxxaxxbcbcxaaxxxdxaxxcbxxcxxxxdaaxxbxxaxxaaxdaaxxdxaddadabxdxcbxxcdaaxxbdxxbxbacdaxxaaadaxxxcbxxxdxaxaxxdaxbbxxdbdbcxbbxabxbaxabcxxbxxxaxxxbbababxxxxxbxxacadabacddacaadabbaabddacaabdxxaxcdbaaaacacbaddacbdbaaadacxxxbxbaddbbbadbdbdaaadaabadadaadabaaaxbadaxdaaxxaxdxxxxxxaxbbaaacdbbdaxdadaaaacabxddaddxadaaxdbaxacxdacxbbxcdaadxxaaxcdxxxdbbxbdacdadabdabcaacdaacdbbbcdacdaaaaaaaadabddbadbdadbbaaddbbxcxbxbdxdxxxxabdadaaacddabadbadabaaabdaadbaadaaabcbbdacbaaxcaxdbaadabdacdbadaadaadbbadbabaadaadaacdaxxdxxxxxxbaxcxbcaxaxxaaxdxxbxxxxaaxacabxxbabxxxdxaxxbxaddaadbccaaaadadabdddaxdxacdxaxcdxaxaxcacxbadxaxbxcadxcacxxababbdbdbddaaaacaaccbdabaabaaadaccccaaxdxxbxaacbxxadaxbxxaxcdbaxxxdxadbcdbaabcdaaadabdddabbbdbabdacdbxxbdbddaabadbabdbbdaccacaacdaaacddxdadxxabxxacxxaxbxdabadadbxxaxxaxxbcacxbxxdaaadabcbbbbdbdadadbdbccacdaabcbaaadabaadaddabbacbacadacdbacdxbacxxxdxxxxbxbxaxxbcdxdacxbabaadbdadbadbbbbbdbabbbddbbcbdbacbdddbaacdbbdacaxadaxxxaxxdaxaacxxddxaxxxxdacdaaddacacbdadaccbddbcbdaabbbcxdbddadxaaaxbaxxxxdxxxxaabaxxxaacdaacxaxdxxaaaxxdbxxacbxxbxbbabxbdxbxdxxcxadaaxbdxacxadxxaaxbacdaaacbbcadadacadbbdabaabbccdbacacdbccdbdacbdbaabacdaxccxdaxdaaxxdaxaxxacxbaxaxxaabxxxbxxxbaaxxaxaxdxabxxxxbcxxxaxdxxdbaxdaaaaaabddbbdaaacdbdbdbaabaadddadbaabcxxdxxxaxcxabdaxxxxdacxxxxbxbcaaaaddbbaacaacdadacdbacaadadbcbcdaabdbdbdacbxxxxcbbadaxaaaaaaaadxxbxbaadaxbabxbxxdxxcxbdxadbxaacxxbaaxdxcxxbxxbadaaacxxaaxaxadbdbaabaadaadaadbacadbaaaaaxbaacxxaxadbxaabccacbdaaadaaadbdbdabbbabcdacacaaaabaaddcdbdaxaacxbxaxaxxbaadbaabbabdadbbbddacaadaabaaaccdbacbbxaxxxbxxxxdbbddaadacdbdbbdaccaadaxaxbdacadacbddbbdadbdaabcbxaxaxxbxbxbcabxxxbxaxxdbxxbdxbbdbbdxxxdxadxxaadaxxaaxxxbabxxbxabbdaacxacaaadbaacbaaxcaaxdadadababbaacbbdacdbcbxxxxbcdxxxbaxxxxbcxxxaxxxdaxxxdaxdxxbxbacdadbxxaacabdbxaxadxabbaaaabdbabaabcdddbbadadacbabacabdabcadbaabcaacbadbbdadaabcbadbbacacbxxxbabxxaabxaadaaccxaadbaaxcxxxbcxxcbbacbbdaaaccbaadbdbabacaadbcxcaacccaaaadaaadacaxxdbdbxxxabxxxaxaxxxdaabaddbcaabddbdabadbcdbdxxdxcacbdaxdbdxdbxcaaxxxdbdxaxxdxabacxacdbaxxxbxxxaddxxdabdxxaacxxaabababadaabdbaaadbbaaaaabbbdaaabdadadbcaabdababadbaadaddadbabdbaabdbbadbaaxcdbbxxbaxaxcxbaxabxxxxdacdbaxbaacaacdacaaccaadadaaadaaaaccbaaaaababbcdbddbdbaabbdbbdabdxxcbaaadadbacbddbacdacdacbaacdadaxxxxxaxxdxaaadacadbacacaddabaadacccadbdaaaaxcadaaxdaxxxcdxadadddbaadbbadbdacdaaabaacdaaaacababxdxaxxaaaccdxxaxbdxxxxbdaxcababdadaaabacdabaacaaacxaxaadacbdaabbdbbbaaabacacdacbbadaaaaacabdbdbbcaadaadxcaxxxabdaacdxbcdxbdacxxxadxabddbcadadadadbaaabbbababbdbabacxxaaxcacbbxaadaxaxaaabbdxxbdxabacbdabbababcdbacadadbcbddaxdxxaaxbdxdxxdacxdaaadbdbababdabadacddadaccdaabbdbaaaacccbdbacbcdabcbdaaaababdbdbdaabbbbadadbxaaxaxaxxxadbxxdxxabxabxxxxxaaaxdxabaxaxxaaaxcdbaadbaaxxcaxxaxxxxdxcadbdacdbddaabcbadbbcbaccbdbaabxaxbxxcbdaaaadxxxbxxcdxxxddaxacdabcxabxccbbcabbbdbdaaccadabacbabaaadacdaabdbaadxabxbxacxxdaxabxacdacxxxdxbxxbxdxxacaxdaxxxxcadbddbdabbaaabbddaacdadaabaaccdxdbxbaxabxaxaadddadbbabaddaaacbaababbdbdaabxxxxabdbxxxaxacxxxxdxcdaxaxbdbxxcxxdxaadbxxabadbdbaacdbaxaxcxbxacxaxddxxadaaacdaaaacbadbaabaadbbbdbadxabaxcdbdbaabdbxxaaaaxcdaaabxcxdbacbxxdxxdadbabxxxaccxxxccdabbxaacaaadbdbbaaaaadaacdbbddbbbadabaaadbdadaaabdaaaxdaxdaxaxxaxdbaababdacaacacdbaaaaabcadbbdadbxbdxaxbdbbaxaabacxaadxxdxdxaxaaaxaacadxxdabbaxaxaaxdabxcxcxcadxbxbxcbxxxxdbxbxxbxbxxabdxxxabddxxaaacddaaabcbdacadacddaaaaaxdxxaxbcdbxadaacdxxaxxxbxabxbdbdaxxbabdaxbxaxxxbdxxcdaxdbdaxaaaxbxbdxaabdxaxxxdaxaadaadbbbxxxxxacadaaacdbdaadbdaddbdbacdabaaxxxxxaabaxdxxxaaxxaxabaxdaxxaxxdaabxxxaaacacbbaabdbaacdaaddddbdabaabdbaaaaacaaadadbdaaababxbaaxaxdbbacxbxxxxaxabxdxdxaxxadxxxadbdaaccdbacdaaaaaacadaacccxxxdxxbxaxdabxaxacdxaxxcbxaxxxxaaxcdaaddacaccacbbaaaaadaadbadaaadbadabdacdacdaaadababbxbbxxaxxcxbaxdxabxxxaxxxabxaxadaxxbdxaacxxxxabadaaxaxxacaadadaadacbadaadacadbacaaadbacbbdadacbacbdaadaxxxbxxxdabdaaaxcaxadxxdxaxcxaabdbadxbxdaxxdbxddbaxdbaxbxdbxxxxxxcxcxxbaxdxbaxdxcxdbxaxxxxaxcadabbaacdddaddbaccbdaadbcbaacxxxcxcaaaxaabadxbbbbaadbbbaaabbdbbdbadbdaxdbabbdacaacbabbadbdbdacaacabdadacxcdbxbxxaxxxxdxxdxacxxdaxddxadbdxdabcxdaccxaxabxxxbaxdxbbxxxxxaaaxadxdxdbbbdxabababxaabxbdxbcabdxxacbaadaxxaadxaaxbxxcxcxbadbxaaaaxxxbxaaadxxxxacxbbxaadadaxabxcxxbbcbxbaaxxxxadxxdxxcdbxaaxaaaaxaxcaaxaxxaxacxxaaxaaabdxxddxcacabadbdbabbcababadaadbadbaaacaadbaxxxxcxxbaxdbxxxaxxbdxdbdaacdbbdabdaaabacbdbabbxxxbbaacxcbdaaxbaacdaadacbadadaaadbabdabcdadadbdaabbacbcbdacdadbaaadbbaacaabxxxadaaxbxxxbbdbcxdxxxxaacxacxbdxxxxaadxbcbaaxbcxbxbxxxbdbxdbbxcxaxbadxcdbabxxbxdbaxxxdbaaxxaxbxxaaaxdbxdxxcxaxxaaaacccbbdbcaaaacdbbcbcaxbxxdbaxaxddabcxaxxacxdaaaabbadbccdabadaababadabbcbabbdbbacbbdaabdbabaaxxbadxxaxxaabdbxaxabdxacxxxxbbxxababaxxaaaabxxbdaxdbxbcdbaxdxxacxcxxxxxaxcxbcxadbbdxxaababxdxcaxaxbdxbbdaxbxaabcbaaabdxadxxabdacdxcxxaxacaxacxxxxxxaaaxcxxcxbxbxxcdxxbxabxdaxxabdbxxxxdbaaxbaaxxcxxxxbxdxxcdxbxaxxxdaxdxxacbaacdbbbabaadbdabdbaabxxxdxxaaxxxxaxddaxaaacxbcxababxbxbbadbdaaxxxxabxaxbabxdxaxaxdxxbxaaxacxacdbxxxbcbxxaxxaxbabaadaxbxbabxxxxbxdaxadxbxxbaabxabdbddxaxaaxxbxxxbbxbaaadbabdbxcbxdxdaxxbdacxabxadabxxxdxddxxccaxxxdaaxxxxxaacbxadaxdxxdbbxaaxxabbbdxdbcacdxdxbaddababacdaaaacbbadbabdbbadbdbbaadxaaabdaxxdaxaxbxxxxbbdxcxbdabxxcaxxbxdxdxcxbdadbdbcbacbdaaaacdaabccaaabdbdaaxaxbdxxxcabdxxxxaxcxdbacxcdaacbxxbxdxxbaxdbcbdxxabddaadbdbdacabacbabdaxbxxcbaxbxxbbxbacxbxaaadacaaaaacbcbdbcbabdbadaxaxaxdabxaxcdbxxbadxxadxabbxxacadbaxaaxxxaxaxxxcxxaxxxdxacxxxxbddaaxxxdbcdbxbcacbbdxaadbbxxbxbdbxbxcdbxdbaxxdxcdbxxaxbxacxxxaxdaxxxxadabbdabccdbdaadabacaadbbcbaabaccxadbaxbdxbbbxabdxxdbxxdbbdbadbacadbbabdaaacbxacdaxbaadaaaddacdaabcabdbdbdacbbbababaabdacxxxaadacbcxdxxbaxdbxcdxcdaaabaxxxxabadxcxbdabcacdabaacdacdaacbdbbabaaaabadxbxxbxxbxxdxbxaaacdadbdbbcbababdabdaaabdbcadxbaxxaxaaaadaababaabdacacbcbaccadbbabxddbadbaabaxxacaaaxcxxbxadabxbxxaxbxdxbbdxabaaxaadxxadxdxaxxacxxbxdxabxxaxaxaxaadxdacaxbxadxxxxxcxxxxbbdabaaaabaacbbaacdbadbbbaxdaxddbbaabdaacbaacdbaacbcddaaccadaaadbacdbaaaxdadadxacxxdaacdxaxxaabbxcaxxbaaxxaaxxbxxdabdbxcxxaxbaaabaxbdbcabbxxacbbbaacbabddadbaadbdaadbdbadabdaccdaaabbdbcaadadaxxcxxcxbcxdxdbdaabaacabdbdbcbadbcccbbaabaacbacdbaaxbbxxaaaxabxbdaaaaxaxxcxdaxdbcxcxadaxxccaaxxaxadadaacbabdaaabaabdacddbdabadxxxxxaxaabxaccdaaxaddxcdxxxxaaxcdxxxxxxxdbbadbbacaaacbdaaabaaadbdbaaacbdaaacdbaaacaadabcdaadacdacbdbabcbdabbaaaadddaabdaaaabxxcdaxxaxxcadbaxxbxaddxcdxxaxxaxxaaadaxbdaxdbcxaaadaxxbbaabcacbaaaaaacdbdadacacbcacbababdbbdbabaaaaaabcacbaadadaacbbadacaxxxcdbxxxbaxxacxbdbxxaxxacaadxxdxxxaxxdxaaxddxbdxdaxbdxaxdabxxadxabxaxcdbdxxabxxdbxbbxxxabaaxaxxbaxxaxxxxcbbxxdxxbbcddadaaadbcaacbadadacbabbadaacbdaccbaddaxxaxxdbdaxxabacxaxbcxbxdbxcdxbxaaxaxdadacxxaxbxxcbxdxxxacdbcaabdbdbaaabcbacdaadaaabdacabxbbdxdaaaaxxxbdxaaxbxcxbbaacbdbddadaabadadaadababdaacacaxxbbxxxxxabadxdaxxxxxxxcbxbdbcxabdxcxxaxbxdbxbxbdxxcbbbaxacxxxxdxcbabxxaxaxabdbdaxxxaxdbaccdaabdaccbaacaccddacdaxbbbdxxcxxdaaaacdbacdabaaaabcaacaabdxbdxaaaxadxxdbxaxddxadbacacccdaabbaaadaccxxdxbaxxxaxaxaaxbbxcaaxbbabcxxbdxbxaxxxxaxcdxcxdaxxcadabccaaaadacabaaabdacddbaaabdaaabbbxbxxaaaxxddxaxdxxcxaaaxbaaxbxxxxaxxadxxaxadxaaaxcdaxabbaaxdbdbaaxddxacaxxxxaxxdbdaxxxxadaxbaxaxdaaaxxbxbaacddxccbaxxxxdxxaxcadaaxaaaadbxxaaxxadbxxbxbddaxxxxbxcxxaaxabdxaxxaabaaaxacxabaxaxdbaaacbaaadadbdaaaababdbadbbdaaddadbacbbaacdaaabdabcbabbaaadaadabbdbaadbbbdaaaaacbabbccadxabcbxxxxxaxxbbxdaxxaaxcdbdxxbbaxxabaadbdxaaxacxxbaxxdbadabdaacbbaaaaccdbabcbaadxxxdxaxacdbbaxbxaaxaacdbaxxcbxaxadaaxdxaaaxdxxxaxcbaxbxbbxxxxabxxabcabaxdxdbxxaaxdbxaacadxxxdaacxxadxadxdxxbdxaacxbadaadxxxxxxdxbdacadaccacaaabdadbbadaadabccbdbadaaaaaaaaaaadbcbdaacabddbadaaabbaacabdaaxdxxxaxabxcbxaxaddaaxdxcxcdxcbaxxxaxbaxbxxxxxxadxxdaxbdxaccdxaxbbxxxacaxcxaxdadaxxdxabxacxbdabaxbdbxxbdxxbbaxcadaaadacaabaaaaadbdbaaaaaaaabaxdxxcaadxxdxdadxbbaxbxdacxxabdbadaabbbccbaabbxcxcaxxxbxxxaadaxaxxxdbbcbbxbaaxaxxacbabxxdadbddxadbbxxdbdbdaxbbacdabdaxbdxxxaxaxxxxxxadbaxbbxdbabacadbdbaadbdbbdbcbabdabbabaccbbbaadbbdadbaddacbcdaxdbdxdbxdbadbacccacbdaaaadddbbdbcdaxxaaxxbdxdaxxacabdxxaxaxcaxxaxacdxcaxbdabadaacdbdbdabdabbaadbacccabaacdxdbxxbxaxaxcadabbxabxbdadbxbabbaxxxaacadaxdxaxdxbxbxdaaxxxdaxxdxdbxdacbabbaaabaaaaaaabadbdadaaccxxdxxadxbxbdxacdxdxxxcbcxbaxbadxxxbaadbdaaacaadaaacbdbdacaaabdbdbccdabxaacdxaaaxabacbddabdaddbaaaacbcaxdbaxdxabbaabadbadaadaaaaadabbacbdbadaccbxdxbxxxaxdxxcxxbaxaxaxaaxdaxaxbbaaaxdxcxxaxbxxxaxbcxxdaxxbcdxbxaaxxxaaacxxxdxxdxadxaabcaaxaadaabaaabcdaaadabbdbdbaaaaxdxbabdbaaxaacbxxaxaxacxadbdxaacxxddxxdaaxxadababxcxdxdxdbaaaxabdxdxacabdaaxxxxaaxxbxdxbxaaccaacdbabaaacabaaaacxdbaddbdxxcxbaaxxxabxbaxaxbxacxaxxaxxdxdaxcxdbadbdbxdacxxxxbaaadbadadbbbabccabbadadbdaadaabcbdadaaadaaacaabacacdbaadaacdxcacxbaaaadacbaabbaacbabbbabdacacbcdaadbaadacabdaacbaaaabbaabadadbabbddddbaaababaaaadxaaacacaaacxxbdaaxdxaxaaaxaxxbaaxxdxaxaxdacxxddabxxdxaxbxxbdxcxadaxbdaxxbxxdacxdaaxxxxaxdxacaabbbdacdbdaacabaaaxxxaaxbabdbdbcddaxxaabxbdaxxxadaaxxaxxxxxcxcxxaaxxxaxaadbxxbadbbdxxaxdaxaxdaxxcbaxxcdxaxxdbaxxbdbxxacxxdxaaxccxaxcabdaacbxaxaxxxxabbaaxadbaacbbbbdacacdbabddaabxxbdxxbbxbxxaacxxxbxdaxaxbaxxddaxaxbxabxxadddacdbdadbdaaadbbacbbdbaxxdxbbxbbdxcbdxxbcbaddaxxcxbdaxbaadaadaxdadaxxxxdacaxxadxxxxbdxbdaxaxcdxadxaaabcaadbxbdaadxcdbbdxxdaxcxaaacaxxxadaabcbaaadabadbaaaadbabbaabdbabaaaaaaddbadaaabxabbaxxacdacdbadacdadaadbbabdbacdbaababbbcdbbxxxcaaxdaadaaaaaaacdbaaccbbabdadaaaacacbabbaaaxxaaxxacxdabxdaxabxxxabacxxxxacxaxxxxbbbaaccbacdadbdababaabadadadaxcbxxxdbxxxaaadxaaxaxadabdadababdacaabdabbbdaaaaacaxacaxaxxxbdaaddxdaaxccadadbxbabxxdxbaaabcdbdbbadbacacddadbbbacbabaccacxaxxbaaxcdbdbdabdaxaxxxxbxxabxaacdbadadaacxbxxdxaxxxxabaabxaaxbbxcdaaxxdaxbxaaxadaaaaxcaxaxxxxxxxxadadaccacdbaadbacbbaaaaxdxxxdbdabdbcxdxaaxxbddbxddbccxcacaxacxxaaaaxdaxbadaxabbdabdaacdaaaaacddabaadbabaaaxcdaaxaxxxbadxbxxbaxdabcddadxxaxacdbbaabdxdxaxbxxdaxxxbabxcbdaabdxxxbdxxxxxcdxcxcbaxdaaxxbxcxbaxdadaxxaxcbababbaacbddadaaadbdabdacbbcaxxxadxdbadaxbdbaaaxaxaxadaxdaxxaadaaxcadabxaaxdbxcdabxxxdbccacxaxbbadbdabddabaaaccaaccbbcdxxxdaxbdxxaaadxaaadbcbaaadabadababbaacdaadaacbaaaaaacbaabaaxaaaxaaxabxaxxxaaadaxaadbxaaxdxbxxbdddbbbbacdbcadbdbabbbdacbaaxaxdxdaxxxcdbxbbdadxacxdbaaxbxxbxaaxxaxbdadadbbbabdbadbacbdbbxbacbaaaaababbadbdbxabxdxacabxxxbbxdxaabadacbdbacbbabdaadbabadbxdxdxaxbaxaaaaxacbxaxbxxaabxxxcdabbxxacaxxxbaaaxdxxdaxaccaacabaadabaadaaabdacbdbabdbdbdaabbcdbdbcaaaddbacacxbbxxaxxadadaxbabdbxxxaxdxadxbxaxddaaabdbbbbdacdbabbadbdbabaaadacdbacdadacdbdbdaadbaabdaccdddbdaadbaaadabadacaabcadaabaaddadxxaxxbcaxbaaaccbdbbacbddbcaaadbaacbdadaabaxbxdbxaxabdbbxcxxdxbdaxbadaxaxxaxaxdaaxaxxbxxaabxcaxbxxadacaxabaacbacdacbxaxbxabbacaaxbxxxaaxxxababaaacxxadaxxxcbxdbxdbabdbcbabbbdbabbcbaabdaccadbcbacbddaaacaaabadadaaaddaddxxbxbxxaxxbxaabxbdbbaxdxxbddxaxbaxxaadxacxdabxbabcdxcaxxxaabxxddxadbxbbaxxxxxcxaxxxxdbbaxcbacdbdbddaaacaacbabaadadxacxdacxaaaxcbcxaxxxxbdaaxcaaxxxbxdxabdbabacabccbaababadaaaabdbxxdxacxaaxcxbxaxxaxadxaxxxaxxddaaxcxaxdacxaaxaaxxdaddadbaxxbxxaaaxxxxaxaaaxcbaaxaxaadabxaxaxbdxxdxaaxxaacxccxaacaacxbdxaxxcxdaaxxxabddxxabaaxabbxxcaxxdbbaxbdaacaxdabaxcxcbadbdbdacdbadaacdacbaddabdabaaabxddxxdaaaaxdxxaabbxxbabxabxaxddaxaxaxcdaxaxxdaxxxxdxdaxbxdxdaaaxacdadaxdxxdaacxxaabdabbbdaaabdadaccdaaaaxcxbabddaaaaaaaabacbbcaaaaadxxdaaxaadaxacbdxxxbxaxdxaccabdadbadbddbdbdacadbdbdbdbacadbcacdbacaadbacbbaaaaaacbdaabbdacdaadaaxxaxcxdxxaxbacddaaaadacbaacddbbbacadaaadxbbcdabxaadxxxbxxaadbddxbxxddaacxxxxaxxxcbdbcxxabxaxxxxxdxacxbdxxxxdbbdaxaxaxdxaacxdaaxbbaxxdbaxxbxxbxxxbaaxbabdbaacdadbdbadaaaaaaaadaaabdacdadaadadadbaaddabdadbdaaaaxxaabaadxxxdxadxxbaaxxxdddbxaxxbxacadxacdxcdxxaxcbacdadbxaabbbdxxaxdxcxxbxxbxxxxdbadabddadbdxxbbxaacxaaxxbdbxbaaddxbdaxbxdxxxbbxxxxaxdxxdxaxcxbaxbdbcbdxxabbbaaabdadaacabcdadbaacaaddabaaxdxxxbcaxacxxbxxabdbcbdacaaccbdaaabdbdbbdbcbcdbdbdbbadabdbxdxddxbxxadaxxxaadxxxbxdxaxaxxxaxxaxccacbadbaxxxaaadaaxxxdxabxbacxxcbaxxxdaxdxxxbxaxcdxaxdadaaxxaxxxxabaabxbaxxaxxaxaaxbacaxadaxdadabxdaxbxacxaxacdacbbddaadbcbbdbaacaaaaaaccabbdaaxbbaxaxxxaxbdxabddbdddadbadabadbacxxabxxxbxdbdxxcxdxaxxbxadaabdbdxxxcabbdbbacaaadbbacdbaaxbdabxdaadbdxaxxcdbxadaxxbxxxbadxxxbaadxbxbdxaxxaaabbdaaabaacdacbaacbddbddadbabbddaxaaabcdaxaaxaxxadxbdabxcxxxxabxbaxdbxxbxbaccdxdbbxbxaxxxxxxbcxacbcaaadaaacdddabdadaaacdacaadaxxxdxcxdabcxadbxxdacbxbxxacbdaacxxcaxdbdbbxcxxxxbxadbaababdbdabdbaadbbxdabdaadbdaadaccaaaddbdaadbaacbxxdacbxdaxxdaxxxxaxaxabaaaacdadbbaaabcaabdacxcdaxxxbdxaabxxadabaxxxacdbabxaaaaaabaddabxaxxbxaxaxxbxxadaaaxacbcdxxxxdxxxbdbdacccdaxdbdaddxbbdxxadxdaaacdaxbcdxxadbdxddadadbadbacdaacbadbaabdbabacdacbabdaaccxaxxdbbxxxbxaxcxcaaxcdxaaxxxbxxxadabadxxxbxxbaxcbaaaadabaadaacbacdbaaabbbdbbbaxacdbbdacbaadabbbdbbadbaaccbdbadaaabaaabxaaaabaxxadbaxdaabbbdabcdbaddaddxxxabdbbcacbaacbaddadbadbcacaxxxcbxbaxabxabxcdacbcdbxcxxxaxdbxacbadbdaaacaccadadadbdacbcdbddacxxxaxxxxxxabbaxxabxxxdxdxadxdbaaaxdxxxbxcdaxxxdxbdxbdabbaddaaacdacbdbadadaadbaacbbdabadbdxbxxxaaxdbxxxdxxbbaaaxabbxxxxdxcdadadaxbbbaxcbxxabbaddxdaadxbadacdxbxacdxxaacxxxxcxaxaaxcdxcaaxxadbbxabacbaxaaxxddxdaxxaacbddabxbbdxaacbaaxdbbxxacdxaxdaxxdxabaxdaaadxaaacaxxxbaadbxxbbbdbaxxbxxxaaaxxaxxxdacbxaxbcxaxbaxxbcaxaccxaxxxxbxxbbxcxdaaxacabxxxbxaxdaaaadbbadaaddaadbaadaaaaacdbcdaaaacdaadacdxxcxacxaaxxbxacxxxdaxaxxcdbabaadaadacabcaacacbdbcabbabdbacdbdbbababdbdbbxxxcdadxacbabxxxxdbdaaxcxxxxdaadxdaaxxaxxbaxbbbxxaaxcaxacaabdbcxxacbabadaabdbdaaadbcdacbdaaadacacbdaabdxaxxxdbxxadbbdaxbaaxaadbxabdxacxxxcbxaxcaxadxxaxxacbxdxcxcxxaxbxdbxbbdxcbaaaxbdaaxxxddadaxdxaacxxcdxaadadaaxxbdbaaxbaxaaxbbxdxdbdabacxxbxaxxxxdadbxxxcxcbaaxbcbdxxxbxaaadbdxxxxbcxxxdbbcxxxxdaacacdaabdbbbdaaadaaaccbdbcaacabaxbadxaxaacxcxxxdxxxdaxabadxxbaxbxxbdbxdxdbdxxdacxdxxcxadxxxcxdxaxaadbbbcxxbxxxbbxacxxxxaxacaxcbxaacaaaxxxxxaababdbdadbbabdbbadbbabdacabbdbdbdbdaadxbaxxdxaacbbxbxxdxbaxxxbdbabdbxxxxdbxabaxbxbdbxaccxbcaxdbcxbdbdxcbaabxdxdbbbxaxaxbxaxaxaaxaxadbcxxaxacbxacxdxaxdbxccbxaxdxcbaxadaxxxxcxdaxxxacdabxaaxbbdbxcdbdxdxcxbbaabxcxbcxxacdxdaaxxxxxadaadaxcbxdaxaxbdaxxaaacdbaabbxbaxababdxcaxbxxaxabbdbaadbcabaaaacbaadbxbxdxdxabxbdaxaxaaaxcadxxxaaxxxdxaccxacbxbacxxbdxaaaaxaddacbabdbaabaabdbaaadbbcdaabdbbbdadbdaadbxdxxaxxdbxbdacbxaaxbbabaccbadaaababdbadbacaaadacbacdaadxaaxbdxxcbaaabdaacadaaacccaadaaadddbbdabacdaabcdaaxbcaaxcxxbcaxxbdbbbdaaaaabdbcbbadbacaadacdaabdaacddbcaaxadaacabdaaaaaabacabacdbadaaaadadbabdadaaaxcddxcaaxbxaxacbaxxxbaxacaaabbacbaaaadbbabbcaabbbdbaxxcxaxdbaacxxcaxaaacxadxxaxbdabbdbadaacbaddacdbdaadbbaadbdxbxbcddacbbbdbcddbbaaabadbxxxbdxaxxaxxbcdxxxdabxcbxxbdxxxcxxxbaxxdbxxxaaxaxaxcaxaaaxxxbdxxdxbdbxxxxdaxxaaxbxxbdbdxxadbacaacadbcdbcacdacdadbacdadaadacdabccabcbbaaadaadaaabacacadbbdxadabdbaaabaaadaacaaaaacbacdbacdbabaabacdacbcaaabxacbaxxadaxbxbdbxadbcaaxacxbaxxxbaxbxcxdbxdbaxxbaxababbaccdaxbdaxxxxaaxaxxccdaxdxxxxxbcaacdbxxxdxxaacxdadaxxxaaccdbccdaadbxabdaadxxbxabaxxxxxxbcdaacbdbcacabaabdadabdbbbdbaddaacdacxxxxxaaaxadxcxdbxxbxbcxbaxcxaxdxdadxxdxdbbxadxxbdxbxbacxbdacaxxaxbcbbbdbbdacadaaaaaadacbcaabxbxaaadabbbacadbadbadbxaaaxxaxadaabddbacdbdbaaaabcbacbdbabdbdaxcbadxxxaxaxxccxaccxaxbxbbcacadadacdbaabdaacabbdaxxaxadxxxdxxxcxxadaaxcaabxxdadbxdxaadbddbadaabbaaaaaabaaccbcdbabcaaaadadxcadacdaxbaxaaacxcxbxxbcbddaabdabaacaadacaadbdaaaaaaaaacacbbdbcdbdadddxbbdbxbxbcxbxbxaxdbxaxxdxabbacaacdadbcaabddabbdbdbaaacbaccdbcdbccaccdbbaaxxaxxxxaxdxcxdbbaxabaadbadaaaaaaaabddbdbdadbcacaaabaaaabacbdadabdbbacbbcbabdaadbbdaaaaabdabbdbdabdabdabddacdaadacadbbdadxaacxxadaaxxxbxxbacdxaacbadadadbbdaaadabdbbacddaaaaaaadbaabddbbbbacbbaaxxxcxxdxcaxxbdaxxxbabxaabddacdbaacbaacabdbacdabddaccddabbabaccbdadbacdadxdxcdbxxaxaxxaxcbxxxxcbbaxbdbdbcxxbbaxxabxaxxacaxdaacxxdxxxxxaacxxxbbbxxddxxxxdxxabdaacbcdbddxcxxcccbcaxdbdxxxbbdbbbbbdbbdabbdbdaaabdbbaadaadabxxdaaxaxxdbdaxbxbdxbbxcbdacbaxxaxdaxxxxbaxxaxxdxbaaxcadaxxaabacxxxacxxcxadxxxabdxdxbdxbxxcxdaxbdaxxxaxabxxaxxcbxabbbaabaaabcdaaadbdbaacbdxxaxxdxxcaadacabababdaacdaabadbbaacbdadbbbdbaacdadbdaabdaaaabaacaacbdacbdxcxbbaadbbbdaaabbcbdaadbabdaacadadaabacaacbdabdbbdbadabddbbdabxbxcxadadbxxxxxacbaxacxbcabbbxbdaxdbdxxbdbxaxbxaxdacbdxxxaxxxxbaxbdxxaxacdxxcxbxbxxxaxbacabbcxadbxxaxxbxxaddbdaxxxabdbxaaxxdbxdxaaaaxcdaxabadadxbadaabbaxacaaaxxaadaxxxaaaaxxbabdbdbcdbaaacaccaabdaccaacdaabadacaacdbdaaadacxxaxcbxdacaabddbxadxbdxxcxaxxxaxaaacdaxaaacdbdbdacaacabaccdbcbcxxadbcbxxxddxdxbxxxaxxxxbxxcxaxxabcxabxaacdxxxaxbxaxaxxxbdaadbdabdbdabdacbbababdbbdxdxaxaxabdxdxdbxxxxaxbabaxbaadaxabaxxxbxacxxxxabdaacxabdbbdbdbbabddbdbaaxcdxxxcbxbdxbdxcxaadxbdxxacxdxxcaxbabxxaaxbaaxxxxxxxxaddbdbaabaxbadaxccdxdbacxbadacxxdxxdaxdaxbacdbbabxxabbaxbcdxxcbddaacbdbacbcbacbaabxaxxxaxbbaaxxxxadbxbxaxcbxxcbxbxbdacxaxxaaabcxdxdaxdbacdbcxxcbxxaxaaaaaaabdadbcdabaacbbbdbadbdaaxbbxabbacdbbcbdaadbaaadadbdxxbxbcbabdbxxxaxbaxxaacdxbdxaxaaadxacbdabaxdxcxaaxxadaxbaxdddxxdaaaxxxxxadxcbxxcbxxacaxadxxdxbxxxaxdxdbadaaxxcdxxbaaxaxacaxbcacaxxxaaaadbbdbdabdaabbdbacdabcdbaadadbdacaacbacaaacaacbbaaxaxxcbxbxbcxabcdxdxcbbdabxbbcxbdbabxabdxxxxbcxcxxxdxbbcbacdacxbabxxaxxxxdbacbaaacacdbdbdadadbbdbcddbxaaacbcdbaxcxxdabcbbdxxcbxxxbabacbbdaadbadaaabacacdbacbadbxxdxxxbdxdbdadacdbadadaacbabadaabdadaadxdxaaxbaxxxaaaxxaadxaxbxbcabaadadacbdacdaccbxaxdxaxxaxxdacxxabdxdxcaxaxaxcxdabaacdbaxacxbdbbxcxxdxxaxababxaaxxacxaxxbadadbbbadabbddbbddbdaaabbddbddbdaadbcacbaxxxxaxacaxbaacdabbaacbdadaadacaadbadbacbbaaaacdbxcaxcxaxxaxxbxbxxxxxxbxcbbaaacdbdbaaacbadbacbdaadacdbbbdbacaaxxcxbbxxxxxbdbdadaaadbaacaaacdacxcdabcdbbdbddbdbadaaccdbacbbbdaaaaabcbbaaaadadaadbbbdbdabbbabaacdabbabbacdacdbabdabbadaaaadbaadaaadaababbabacbacddxxbacxxdbddbacbdaaccbaaaaadbaaabcdacdbbbdaaacbdbdbcddaabbaaaaaacdbdaadbdbaaacbaaccbdbxadxaabaxaxaabxxdbxbcabdadbaxaadbddaadbabdaaaadacaadxddxxdxaaxdbaaadacbbcbabbaaadadbaaaaxaabxxxacadxacxabaaadbdddaaaddaaaaacabbadbadabadadxadaxadxacxxxaaaxdabccbcdaaaabdbaaadbbacdbbdbadacaxdxadaxxdxabbdxxxbxbxxxxxacacdaxcxdbdxcdxaaaaxxbxdxaadabadbbacbbbdbaaaadxadxxxaxacxxbbdxaaxadxdaaxaxbaxxcbxxxxxadaaaxdbxxdbdaxaxxbxxaxbbdbxdbdaxcxxaxxxxxaacbcdadbdabdacdaababdaacxxbxdbdaaadbxxxaxxbbdaxdaaxbaxbxxabxxadabbaaaccadabdaacaacbdaaabbbbaaaadbddbdbbabddacacadaddacbacdbaabcadaaaadadacdadaxcbadacbdbadadbdbaaababadacadaadaaddabadbdacbabaadaaabacaabadxaxxaxaxbxcxbabxaaxcbxdbdxcaaxxbbabaxbaaxddxdbxbdxxbddabxdaadxdxdxcbadbdaabaacbbadacbdaacbddxacxxxbaxxbcaxaxabaadbdxaxxxbaaxbxdxxbbxxcxxxbdaabxxxbcdxxxdbdxxacbxacbadaabadaabbcbdaaabacbcddacxbxxxxxxdaaxbxxcxxdbxaxxxaxdaaaaaaaacbaxdxxxbdaxadaxdbdbcaacxxdbbdxcbdbxxdbcxxxbaxxacbdxdacbbdacabxdaxxxaaxxxxaadxxabxabxdaacxxbxdxxacaxdaxdxadbacdbcdbaababdbbaadbaaadbabdacddbcdbdacaaadacabdddbbbabbadaabdadaaabxbdxdaxxaxdxaaxbxxbadbxxdxaaaacxacabdabadaaababacacaadxdxxadxcdadadadaacbdbababdxxaaaxadbbaxxbxdxxaxdxxxxacadxbaxaaxxaaxaabbccdxbaxxxdxbbbxdxxcxxaxxcxaabdxxxxcdaxbabxxbacbbxaxadxadxbxbxbxxaxxxxadacddxccxxaxaxxxxbdxddxxxaxcacdadbdbdbababadadabacacdaabxdbdxdbdaxabdaxcaaxaxxxbdxxbxdxxbxxaddbaxxdaxbaacacdadbadaaacdabdaabdabdbdacdadbbcbadbaaccaabaadbdacdxdbxadxbxaxxxdxxddaaxxacxaaxdxcbdbcaxxdaaaaxcdxxcxbddxacaxbxxdxxaadxxxbbxaxbcxaxxxaaxaxxbbbaaxxxaabdaabxxbacxaaxaxadbadaxdaxbdaxxxxbddbxabxbdxdadbxxcdxaxxxxxdaaacacbaabdxxaxxaaacdxaaxbxxcdxdaadaaxxxxxxaxddxacxbbacxxaxxccdddxdbxaxaxcxaxbaaaaadaacxdaxxaacxxxaxcxaaaxadxxcxacxaxaxacbcbdacaaadbaccacbdcacaxxxaacdbbxxcadbadaacdadacaccbdbcdbacbdbaxxxxaxxaxaacbbaxbbbacabbdbdbbbbabdaacadaaabbcdadxacxxacxaaxxaxxcaaadxbxxcbxxaxabddabaxxaxaabxaxxcdaaccdbbxxdxdaaxcxxcxxaaxxaxbaaaxaxxaxaxadaxxcadaaaxaxaxxaxxxxxaacxbxbcdabbacxaxxaacaaxbadaxxbdxxxabcbdxdbabxbxdaxbxbaccdbcxxxcxxxddxdxxxaxbxcxdxaxdxbxxaxcbxabdxdxaabxdxxaxcxxaxxaadbxcbbxxxxacxdxdaxxdabbadxxbcxxaaaacbbabcaaabadbdbdbdxcbdbxbdxbaxxxxxdxbxdbabacxdbbddbxxabbadbdxbbaaaabxxaxxxbxcxxxxabxbdxaabaxdbxxdxcaabcxbdxbdbdxbxaxbcbaaadxxabdbbcxxdaabxdbdaxxdbaxxadaxxaxbdbbdabxxxdbbaxxabdaxaadaxaxbxcxxbdxcdaaxaaxaxdaxcxxdaaxxadabxaxacbdbdadbbdbbdddddbbdbaadaadbbcdxccbxaaxdacadadbabaabbaabddbbbbddadaacbddbacbaaddabdaadabaaabbacbabaaadbaaabbdacxaxbddaxxadacacxdxddbdaadadbbdaabacacbdaacaaacababbcdabdaxdxxadabbdaacabacdabdbaaadabdacaaadbaacxaaxaadbaxdaabdxxxbxxxxaadxcxxxxxacxbbaxdxaaxcdabdadadacbbdaaaaaacddxxacabcdbcdacdaadaacbdbbadbdaaxcdbacacabbadaabdbbacbddbadabacbaxbxaaxxccxxaxbxbxxaaxabxdadbxaxadxxdaxcbxadbabaxaxadaxcxacxbdbxaaddaadaaaddbccacbdaadadbbbbabdacdaaaaxbdaxxxbbcbdxabbcdbaaxaxxxxcdxaxcbxabxcbdaxbxaxdacdaabadbdadaaabacabdabxcadxxxbbbaaabaxbcbaxdaaacxaabadabbacdbaaadaabaadddbadaddaabacdbxdxbxxbbacxxbxbxaxxdxdacdxxxaxdbxxxxcbxxdbabxbxxabacacdadbxxacxaxcxxaxbxxcxdbddacxxcxaxxxaxxbdbxddaxbxxxabaxxdbabdbbcdacdbdadaccaababdaaacdaaxcxxaaaacxxxdxxxabxxacxadxadaaxacaxxaxbdxbxbxxdaxxxacxxcbacbxdxbdxxddxcdabbbddxbxxxxxxadaxbdacaxddbxdbadxbaxaxxxccaadbbdabadbaaddbdacdbaaxxxbaxcaaababcdadbaaabdaacdbabadbcdbdbddaabadxxabxdaadbbbcbbaacdbaabdbbbadbcacbdbaacbaabcxxxacbbcbacabaaadabaadacbdbaxdaaxxbabdxbxaaxxxadxxdxxxxxaxadxxdbadbxxbxacxxxxxaaxdbacadxxccdadbaadacdbdadaabddbdabxxxcxdbadxacxccadbdxaxxdxdabbxccxxdxcxdaxbxbxdaxdbxabxxadababdadaaadadbdaaaaadbdbbdbaaxxxabbcaccaaadaaaccdbdbdacbaabacdxxbdaaxbadbdxcxxxcbdaxaxxdxacbdxbxxxxaxbaxcdxxxbxxxdxcabxaxdxxdbaacabadbdacdbabbcdbaacabdaabaabcbaaadbbbbbaadbdaacdbacdxaacaababdbbbadaabaaabbaadbabbbaadaadacbdaadbbcdbcddaabxcxbdxaxaxxaaxxxabccdabaaaaaabacddxxxdxaabadxbxxxaacbdacxxaaaccddadabbdaaabdaaaxacbaxcbdxadbdbbaabddbabcbbbaaadacaadbbadbdddacdaaabcaacabdaxxaabaaxccxaxadabdaaabbabaadacbdaaadaacaaacdabbaadbdbddbaaxxcxdadxxcxbxadxbxdaccxxbxxxbxdxxdaaxbabaaxdxdxbxxxbadbxxaacbdbaadbadbbacbdbacaadxxxxxcdxxxbxadxaadaaabaadadaaacbabdabcaaacddbbabbdaadacbxcbxxxdxaxdxbxaxxxbxaabdxbdbxadxxbaxcabxcbxaxccdabaaaaacdaaacbdabdxxdadaxcaaxxdxabcacacbxacbxxcbxabcacxbbxbxxxxadxxdxdxdxxaxacdxbaxcdacddxadbcaaxdxaxadxxaaxxxxbaxaaxxbxaaxaxxcbxaxxxxaxxbxxacaxdaxxxadabdbaaaacdabcdbaabacbabcbdbcdaaadbcccbdaacaaaacaaddacxaaaxbcaxbbxaxxxaxdbdxdaxxdxdaaxbxbaxbaaaxababxxxbdbaabddxxabaabdbaadbdaabbaababbbbdbaabdadbadaaxbdaxxxbdbxxadbaxbxaadbdadabdaacabaacaababacbaadbaaaabaxxbxaxxxbdadxabdxaaxxxxxxaxbxxacaaaadxxbxxxbbxxacaaaxbacxdxaxaaabdxdbcdxcdbdaabbacdbddabdaaadbdbacabacdaacaacbaadbacddbacdbdxccxxxcxbabbxaaabaxcbbbdxxaxdbacbaxxaxxaxdxxbdaadbadacdbacbdabaadabbdadaadbadabaabacbxaadbcbxxxbxbxdxxcacaxaxacadxaabxcbxxccxdxbdxaxdaaxaabbbdbdbbccddddaaddacbdabdaddadadacbaadbxabdbaadbadbdabbdaaaaaaaaaxcxaccxcxbxaaaxxbdabxcxxxdxdxxbbxadbdabaacxaxabxbxxxxaccxxbbxxaaxbdxdxabcdbaacbabaadabadbdaacdabbaabaabxdxddbxxbbddbxaxdadxxxdbxbbacxcxxaxxcbxxdxdbxdbxxadxbabaaaxxxabaabdacabcacbddaaaadbbaaxaxxxxcbdxxacxxaaxacdaxabcxccdxdadaaxabaxaxaxbdxdadxxaxdxxdbadaadadbabadaadbcbdaabdaaxaxbdbxbxbxacxxxxcadxaadaaaaaaadbdaxbdxbxxxbxdaaaaaaddbdaabaaaaaadbacdbabaaaaaaccbbbdaaacdadaaxxabaxaxdbaaaxdadxdxdaxaxaaxxadaxcbbbdabbdbdbdbabadadbcbxddbxaxadxcxacdaaxdabcbxbxxxaaabccbadaabbaaaacbabbbacbdabdabcbdaaaaaabaaxbdxbdbxaxdaddbxbbbbcbbxaxdaxdxxxbacxxxdbbbbadabddbccdaaabdaaxabxxaacdxaaaxcxdbxxxaxaxxxcxxbbaxxbdaaxxdaxacdbaadacddbccdbbdbdxcxaxxbxaxxadaabdxxxaaabxbxdxacxbbxdbbbbxxaxxxbaxbdadxdbdacbbacdabdbaaddaaabbdddbbdacbaadbaaaabbdbaaxaaxcdxdxdbbdadaxxxxdacxdabaxxaxcxaxxdxddxxxxbdbdaxxcdxxxbxbxbaacaaaxxxxxxxxaxbacxbbxxaxxxaadbdadbaaacaaaaadacacbaabbacacdadbaddbaababcbcdaaxxbbacdacaacdabadbdabbadbcddabdaaxaxxaxdxdaxdacdxbxxxaxxxdxaaaxaxdxxcbxcacbxabxbxxxxcacxadbaaxacaaxxaxcaaxabxxbaaxaxxxbbaxxaaadaxxbcxdbabbabxxcxxaacbxdaccacaadacadbdacaaaabdbaaxbaaxbxdxdbacaxbabxdxxdxxabbdbcbcxxxbaadbbababacbadbcbbdddadbaxbxxaxadxxxabxxxcdaaxbbadxaaxxxxabbxxxacdaaaacbdaabdaadxbaaxaxbdxxaadbdbaabaacdaaacacaddbacdaabaadabdacacxxbdbabbbaabcaaaaacbbbacaabaadbdaaadbbbxxxddxxbxxaxxaxxbabxxdxbbaccxabxxxxxaxcabdbxaxxxbaxcbdaaxbabxcdabbaabcbdaxdbaxbdxaxxxxxxdbabdaaxxaxxaaxabxabdbdababcdbdbaabdbabaacaaacxxxxxcxdbacxaaxxxxaxxadbaadbdbdbbaaacbcabaaaaacbaddadbaaacdabaaxcacdaxbxbxbacxxaxaccaaaaccacbbacdadacdacaaacdxbxdbaxdxdxxbxcxxbbcaaaabdbcbacbaabcdadacaxaaxcxbdxaaaxdxxxxxbbaacbababcbbcbaaabadacaaxaxxbxbxbabaxxxdxxxxxaacxaaacdacdbdbdacdbaaacdbdacdacbcdaaaaccbaabcbdaccbdacbxbxxdxxxaaxxbacaxxdxxaaxbdbbxxdbdadaxbadaxxxaaccxdaxadxxbxxaaddxxdxddaaacxdxbxbaxxxaxxcxxaxaxxaxdaxabcbaxxacdxxxxdxaxxaxxabbxcadadbdbdaccdbbddaaaabdddabaaabcbadacbadaadabdaabdbbbacaaababbcxxacxaxxcdbbxbdbxbaabxaxaxdbdxxbddxaxbacacaabacdbaaaccacbaxxaabaaxdxacdbcdaaaadbbcaacaabdbadabbdbxaaaxxaxbbacbdaaaxaxcbdxdadxxaxaxbaaaxxdaacdaxadbbacaabxxxbddaaabbabdbbbdbdbabaacdbaaacaaaxdxaxbxaxxcxcdacbdaxaaxxbacdadbaxaxbdabdaxaxbxxbxbdxxxacdxbxdaxdxbxdbaxbxdxabadaaaaaadacdacaadaaaacxabxbxxddaxaxxaxcdbxbaaxaxaxxacxaxxxadaxbxaxaxdxacxxxaadbadadaabxbdxdaxxxbxdbxaxaxxaxaxdbxabxaxdxdbbxxbbxxdadaaxxxxxxdaxxcaacaaxxaxxxbxxxdaxbabbxxbdaaxxaaxacbxbxbxdbaaaabbxxxxdaaxaaxbxxcxabxcaxaacdxabaxddbdaxxxabaxdbxxababbxxdbdacdadbdbdadbdbdaccddaabaxcbxaxaxxxdbbccbbdbabdaabacbbaabaacbcabdbabdbbaddadbdbaddaadacaabaacdabdbbbacbabaaaabdaaacdadbabcadbaaabcdxaxxxbbadaacdbdbabdbaaacdadaddbxxbdxxcaxbbxaaaxbxxaxbxxxbxdabdxxdxxxxaabxxxaxxaddaaacxxadxacdacdxxdxxxbaaaxdxbadxxxxaxcdxaacdaxxxbacxxxabxxdxxxcxaxdxabdbxxxxxdaxbaxaababacbadaadbcaaabaaacbbaabadbababdbcadbdbaxxabdxdxxxxdaxaxxabbcbabaacdabdaaaacdacaxaaaxxdxaxbdaaaadaabaaaadbcdbbdbadacdaacdaaabbacbxxbcdxaaxxccxacbacbcbdaaadaacabdabacbabaaabdbaaaaxxbxxcbbxbdbxxbxxxxbxbaxadbxdxcadaadbaaadacdbdbdbbbbaaabdabdacbaaababbdabcdxccxbxabxcaxxadxdaxxbxddbdbdbcxaxadaxaxaxxxdaaxbxaabaadadbbadaaadacabaaadxbxxxcxxxaxbdaacaxcbdxbxxabxdbbbadbxxbxaxaacxxxbxbadacbbaaccddbbcdbdbaabbadbadbaabxbaxdbdbacxabxbxxxbdaxabcdacdaxaxaabxbdbdbdxxxacbxbdddaadaacbdaccdacdbbdbabaaabbaabdxxxcxxbaabadbaabdadbaacdaacbabcbbbadxxxaacdxbxxxdxdxaaxaxaxdaxxxxdbdabaaccabdacccdadababxbaaxdbcbdxxacxcxxacaxxdaaacxxcadbcbacbdbcacabccacbadaadaaacbdbbaxcdxaxaaxadaxxbxbaaxdaxdxxxxaxbxdxxbcxdbdxxxadbadaaacdaaddadbdacdaabbdaacdbaaabxcxxabaxbbaaxxxxdbbdbdxcxdadxaxbxaccaxadxcaxxaddxaxadxxadbbacbdacacdaabaacdbacaacaacbdaacacbdadbbaacaacdaaabaacbdaaaaacaaacaadabaacdbdbbxaaabxdxxbxbcbxxxcbdaxdxaxxadxbbxdaxbxxxbaxdbdbbadabdaaddbdabacaaddbbaaabcadaaacbbbadbbabacbacacaaababddabadbacabbacbaaacdbbaacacbaaabdbdbabdabcdacddaaxdabxxxxadbxdbxdbbxxbxbbaaxabacadaadaaadaaaaaxdxaaaxdbcdxccxaxcxxadadxbaabxxabdabxaxxbdxddxdxbxxxaxddacbddbaadbadbabbaaaababadadbbaacbaaaaaacbbccaabxcxxaxxxaaaxaxxcxaaxxcccaadaaabaaaaaxcdaxbbaaddbaacadaaaadbaaacdbabcxaxxxaaxxxdaxbaxxbbdaadabbcdbcbacbbbbadaaacacbdbdbaaxxadxxxbcbadxaxaxcdxxaxdbaaxxaxxxabxbbacaabadaxxxxxaxcxxxdxxacdbdaxbdxbabaadbabddbdddadbbbbdaabdaxdaaxxbxaaxxxdxbdxxbdaadadbbaabdaaccbaadbdacaadadaxdxaxbaccxcbxbdbaxbdxxxxacbbxbcdaxdaacdxabaxxxxxxxxdxxdbdxaacbxxxxaxabxaadbabadaadaddabababdbdbaxbxbxbbaaxdxxxxxabxxacbcxadbxabxcbdxdaxxaxxcdaxbdabxxcacabdaxxxxbxaxdabdaadbaabaaabdacbcdadaabdbcadaxxacdxxbacdacxaxcxxaababbadbdaxxaxxxaxaxxadbaaaaxaxaadxbxcaccbdxcbxxcbaababababcdacbadaddbacdabbabxaadaaxaxxxdxxxdaadbacdacbadbbxbxcdxcbdacaxbdaadaabcaaaacadbbcdbabacabadbbaaaxbxxdxcxadbacaaacdbdaxbxxxxddxaaxxbbbxxcxxcaaadbbdabdxcaxdbaaxxcdadadacacabadxdbxbxxxxaxbxxbdbbxbxxxbxxxxdxxbxaxbadxaaxxdbaacxabxbxbxxcbbbbdabaccacbaabbbbdbxaadaacaaxbdxdaxdaxaxdaxcbaxbxaxaadxaxaaxbbxbxdaxcddxxxdxxxbdxxaxaxxxaaadbdaxxdxxbxxxxaxxbxbxxaaacxxxxaxxbccaababbabdaabddddacdaabdaacbdddabcabadaaaaadbbcbbaabdaacdbbdbdaaaxxacdacdabbdaabddaaabbdxxcadxcxaxabaxbaxdxbxbdxaaacbdxxacacbxbaabxxdabaxxcbaxxcxaaxadxxxxaaxaxabaaxcbcbxxaaabbxbxccaaadbaxxadabbbxacxxcbxbaacbabxabxxxxaxbxbbacxxbaaxxaxdxxxxbacaxxaxxbaabcxadxbxaaacdbxxxxbdxdxddabbaabbabbdaadaadbcdbadacacdbdacbbbbadbbaaaabdaxbabxxxadbaacaacdaaxbabxbbxbdaaxdxdbaaadaxxbxbcdbdxxcxbbbxdbadaaccaadabaacaacbdaaabaaadaxxxaxaacdaaababaadabccabdxaadaadbbbabaacbdbaabdbddbacacdbcbxbaxbaxdbabbaaabbbbdabaaabdbcacbbadaaacdadaacdbaababdadacdaaaadaaaadadbdbbddadaaaaaaacaadbaabdabadbadabacbabdaaacxbabcxdaxxxxxdbdadacbdbbaaaadbcbaabdbbdaabxdadxxaxacbxxdxacbdaadacbdbacdbbadababaaaacabbdabcabbbacbbdadbaaadaabaxcxdbdaxcbdadaabbaaaabdbaddbabcdacdbabacdbdaacddbcadaaxbadxcxxbxxdabxaxcxacdbaccacbaabddaadaabdacdbcxxxcbxdbxxxxxdbcxxadxaacxbdacxbxxxadxaxdbxcbdxxcxacaaxdxxabdbdbcacdbxdaxcxdaxdbcxaaxadxxabxxaaxxxxdbcaxaaadxcaadbxxxaxxbxxccbxxbxxxxdxxcaaxaxdaxbadaxxaacxacxxxbxbaxaxdxabxaxadaxaxacxdabaxcdxcabxadabdbacacdabcbacdacadbaababbbdadbaacdbadbdbaaaababdbaadaabacbdacddbbaabxaaaaadabdbabbcaacaaabdbaxbcbxxdaaaabbxxabxadbabcacbacbadaccacacbdbaaaabacdaccbxcccdbxacxxabacdxxabxxabxxxxbxxacbbabbbdaddababcadbbdadbdabccdbdadbdaaaabaabcdbddaaadbbbadaaadbdbacxxbxxcxacaxxbxcxaxaadaxxxdaaxacdadadacacbdabcbaabaacbdabaaaxcdadbxxaaaxacxadbxadxbadaccaddbbaaadacdbdaaaacdaaabbdaxdxxaxbaxxxaacxacdxdxbaxxxxbaxxdaxxbdaxxxdbaaxcbdbcdbbacacdabbcbbaacdbbadabbacdxxxdbxabxdaaaxabcxxaaxxabcxaxxxbxaddbdaxaxxdabxdxaxaaaxaaadxxadaxbaxaxdbbxbxxaxxaaxaaddadbbaabadbbcbaacbcdaxbbaaddadbbbbabcbacdadadxdbxadaddaxbcxxdxxxbaabbaaabdbabdbacdaaaabbxdxaxdxcxxcxaxdxcxxbadxxxbdxbxbdxxaxacxbdxxxxxxdxaaaacdbbbdacdbcdadbacdbdacbaacbxxxaddacdadbbabaaacdbaabaaababdadaaacaaxabcxxdxdbdaxxxbxxcdaaxabxxbdacxaxaxxdbaxxxxxbaxxabcddaabxaadxaxxabdxxbxdxaabxxxxxcxxdxxaxxbaccbxxxxxbaxxxbcacdbbaaacabadbcdaccdaacbdacxdxxxxabdxbxxxbaaaxdbbxxadacbxxxxbxxcacxdacbddadabbaacdadadabxacaxacdbxxxxaxcxbxdxxbaxxaaxaxxaaabadaabxaxcdbxxxxxdacxxxxbbxaaxbaaxxxxxbbabdxcxxaxdxabxxxbaxxaaacdxacxbxxacabaxxbxxbbxxxxxdxxxaxxbdbdbbcdaadbdbabdbdacaaxadxxbaabxbxxbdbaxxxxcxacxdaadxxdxbbbcxxdxbbdaxbadaxaxadaxxxdabxaxacxxbaxcbxxadadxdaacxxcbdxcdacbaxaxbddbaxxcxcxbbdabbdbxxaxxdaaxaxaxadxxbxxxdbbbadadxxaaxxxxxcbdxxbaxbxacxcdbadaxxdaaxxacbcdabbdbaaacbbadabdabbdbxxxcxbcdxdxaxddxxdaaaacxxxxxbxaaxxbxbdbaxxdbddacxxdbaaxaxbaaxxaaxxaxdxaxxxxdxadbdxaxxdbxdaxcaxxxbdabbaabxbbbcxxbddaaxdbcbxxxdxdaxcxxaxxaxxxdaxdacxcaacadaaaadacaacdabbddbdbcxdxcxxxaaadacddbaaaaadaadbdbaaaaccxbxxaaaabdbbbdbbadbacbaabdbacbdbadbdabadbdbbabdbadacbabadxxbaaabdabxdabbdbaxdxcxxxxbxdxbaxbxdbxaddxacxadaxxdaxbxxxxxaxbaaxaxaxxcaxbbxaadaaacbxxxxxxaacxxxaaxbcdxxcdxxccxacxacxcxxbcxxxxbxcxababaaadabcadbdaaaccdbacddaxxdxxbbxabxdaabdbaadadacccacbbdaaxxxddbxdaaabcbbabddaabaadbadbbdbaccbxaabcbxxbddxacxdxabaabxcbdxxcaxaxxabxxaaxabbxdbdadxdxadxdxbxxxxxcxxbcbaxaaxdabxxcdxaxxxabxxxbdaadbxxdxxbxxxabaxacxdadbbababacdbabbaadbdadaabdadadadacbdaaaaabbdbcdaaadacxaxabadbcdabcdbadbabcabbdaxxxxbacaabxaaaxabbxxacbaaxcaxdbaxbdxaaaxxxxxcbaaxacxdbabadadbacdxaxaaxabxxxaxxxxxxaacdaabddbadxxxdxaxxaxbbdxxbxdbaaaabadaabdbxaxacdbxacbxbxadbxxxbxbdxxaaxxxxbdabdaaaaabdabdaacabddbdbaaabaadxadxxaaxxdaxaxaadaacddxabdaadadaxxbaxxxxbaadbxxxaabaxaccbdbaaxaadbdbcaaxxbdddxxxxbxbbaaxbabdbxxabxaacbxxxxdbdbxbaaacbbacadbdbdbcbacacbadacddbcxaxxxxxdbaxddbxxxdxxxxbbaxaxaaxdxxaxxabdaxbxxdxxaxxaxxcdxxdbbaxdbxdbdxbxxbaaxdbxxbxabaxxxcbcdaabaxbaaxbaaababdaacdaaaadabdbaaaacabbdbxbcxxadxaadaddbdbbadaaaacbcdbcaccaxxxxcdabxxacxxxaxbxxxdaxdbabdxaacdbxxcacxxxbbdbadacbcbcadaaaaacbaxxbaxaxadbaxcxdxxbdaabcbabacdaadaadbaababbbbdbabaccdaabdbbbaaacdabcaaaadbddbccadbxaaaxbacxxcabdxxcacdacaaxdxdaadbdbbbacdbaabbdbaaabadbbdacbaaabcbaacbdacbaacacxbxacxdxadaxdbbxdbdabcadbbaaadabaaadbbabbadbacccdxdabxbaxaxaxaaacaadxbdxcdxdxxbbdaxxxacdbbxxcaxdbdaddbacbccbbaacaaadbbbdbdbbdbacxxaadxaaxdbbaddadaadadaadadbababbbaacaxxxaxbxdaxbaxdxxabdaaddacbdacdbdababadbdabbaacdbabacdbdaaacbaaaabddabadbabdaaadabxxaxxxbaaaxccbbxxbdbbaxbxaaxaxbxbaaabdxabxaaddaaxxbaxaxaxbbdxxdbdxxaxcbbcxdbxxdbdbbddaxaaxaxxxdxxxxxcxxxadbbadbdbcabaaacbddaaadadaacacbaxdxdxaxxxaxxdbabdxxxxdbaxbxabaxbbxxbxcxacaaaxaxxaxaxdbaxxdxaaxbdxaxxbxxaabcabxbbcxdabaaaxbacxxxcaabaaadaaadbdxdbabxxdxadaaxxaxxaaxxbcxadxbdxxdxabdxxdacxbbaxxcbxxadaxxxxxxxxxaabbaaxdbddbabacdbbadbcbaaaaaadacbaaabbbbbbdxdbxdbaxbaxbdbxaaaaababaxaaaxbdxaxcxcdbacbddbdbcbaaccdaadaddacdbcdadacaxxcxacaadadbcdaabdaaaaaabddaddbacaadbaaaadabbadacbbdbbcdabacdaabdbdacdbacdaaxcaxacbxcacabxaaddabdaaxabcxxxdbxbaxxadacdxaxbxbxbxbxdaaxaxdxdaaabcadababaaabaaacdaadadaaaaadbacadbadaadaadbbdbxbcabbxxcaaaxxbcbxdxxxxbaaxdbbbdxaaxxxaaxacabdaxxxadaxdaxxxbcxxadxacxaxxxaxaaxadxxabxdxddxcxxxaxxbxxbbaxbdbaxaxxdbaaxxbxdbaxaxbabacbaacbdacaabbdbacdaabacdbacbdaxxaaxxdxxbacdxxxdacbadbbbadabxxaxacdbdaacbbacccacaaabadaaaadbdaaadaaxxddxacbaxcacxcdxaabxdxxadxbbxaxbxxacaadxaxxadacaxdxaaxdaaxxadbcxxaxcbdxbaadacdbabdabacbdaabcxaxbxcaxacdbdbxbxbxdadabacaabaaacdbdbadacacdabbbdaaaacabdaxxabaadbdbdbadadadabddbbdbaxaxaxxdxbacbxxaxxxxxdacaxbaxxdacbbxaddbbdbbadaxabcccxbxbdbdxdaxbxxbxbbaaadxbxcxadbcxxbaxxdaaadacbbcdacbbdacdaaabdaadadbacbdacdbbddaaabxxaxxxxxbxbxaxaaabaaxcxaxxbxacbacdxxacabxbxbdxdbcaaxaxxaaxxxdbaadaxxbdbaaaaxbxcxxdxxxxxxaxaxxdxdaxdxaccbcaaacbadacdacbbddbabdaaaadadxaaaaabcaaaabbababdbdaaacabaaaaaacbdbdbddbdadbcdaabaadaadacbacdxdbdaxxxxxdxabaaxdaxbbbaxaxaxxxacxxxaxacxxdaxcaabcabxbbxbxadaxcbxaxxxcxadbdxdbxbbxxxxadbaxdxcxdaxdaxxabdxaxdbdbxxxxbadaxxxaccdbadaaacbcdaadbacbdaaabadaacaacaaaaaxxabaaxxxxaaaxxxdxdabxacadaxadbxaaacadacxbxbdxbbddadbacdaaabaacbaccaabadbacdbadbdaabdabadxdbxxaaddaxbdababadadacddbadadaccdaaabbbaadaabdababdaccdaacaabcbcdbbdadacdaababdabxaxdxxdxxxaaxxxxbcxxxbaxxxxbxaxbxdabababxdxxbccdbbdbcaaaabcbdacaxxaaaaacdacdadacaaacbdabacdxxxxxbacxdbabxdxadxbxxcbdxxxxacxaxdaxaaacxxaxdxadxxbxxcxbaxddbdaxxdxxacbdbdxxaxdxaxcaadadaxaxxxaxabbddaxxbxbxbxaaxccbbcabddadbaacbdabaababdacacbdaxxaxaxdxxaxbbxdbxdbxdbbaaxaxxxxdaaxbcdbbcaabaccbdadbaabdaaaxxccdadaxdaxaxdxxabxbdxaxxxdxxxdxxdbxaacdadbbdbbccbbdaaaabbccddbdadbdbxxcaxcxxadadbbaaaaaadbdabdbbdbdbddadaadacxxadxddxxdaacdaxxxbdbabcbacadadbdadbbbcdbbaaaaaaaxadxxxaxbacaxxxxxxdxaaxdxcadxxxbxdxxbxdabxxbxdaacbdbdxxabbcxaaaxbbaxcxacdxbxxdxxxaaaxbaaxacaxbxxddxccdbdxbxxdbxxxxxbdxaxxxdxxccaaaadxadxbxcaxxaxxxdadaxdaxbaxxbbxdbxbaxdadbabxxxxbxxxxxxbxaabxbxccaaxxxcdxbbxxxadxaaxbxcxcabaxdxxxaxaxcccdbbaadbdabacbaadbxcaxbcadbacdbbdaabcdaxadxxdadxxaaxxxbxcxbxxabdaxdxabdxxbxbdbdbacaacabdaadadadbbaacdbbdaaaadbbbaacabddaaaxdxaaxxbbabaxxxaxxxxdxdxaxbxxabaxaadxaaadbdaxbxabddxxdxxbcbxaaddaccdaxcxxdadbbadaaaaaadbdbdacadadadabdadacaadabbccacdabadadbcbbbbbdbababacbadbcaaaadbabaadxcaaaxabbxaxdaxdxbdbxxaabdxxcbxdaxxdxaxaabbacxbacxabxxxaxbxbxxxaaaaxadbxaaaxbxxaaxcxxxxxacxdababbdabadaadaaccxbaxaadadxcxdxbxaxxdbxbaaxxadxbadbaacddabbdbaaadabaabbdddbdacadxaaxxadbbbbabcbaxxaxabbadacbcdacabadaaaacabaaaccdaaxabbbaxcbbaxbbbaxcadaaaadbdbaaacaacdbabdacdbbdadaabcaacabbaxcxabbcaxcxxxxxbxxxxxdaaaadbcaacaddabdbabacaaabaaaacadaacdabdacbdabacacaaacbbcbbadabxaxadaxxdxxxbxaaaaxxxxaaccbdaxdddaaddabdabcadadaaadadaccbccaadadbdbdbabbdaabdaabbbacababaacbacadaaaadbbdxxxcbaadxdaaabbdaddabdbaaabbabdbdaccdaacbaabaaccdaxxbdaxcbabxbxacaxbaxaxbxxbcxxxbbaacxdxxdbxabxaxxxaxaxcabxaxadxxdabaacacbdbabdddbacbaacxbaxaaxadbxabaxxxxbbaaaxddbaacbxdabacxxxxadbaxxaaxaxdbaxcxaaacdbdbacacbdbbbbaaccaaacbbcbdbbdacadaxdxxxdxxcxbacbdacabxacdxdxxaxxacdxxaxaaaxaaaxbxxaadbxaabaabxbdaxxxcaxxxxxxxxabxxbacdaaaabacbaacdbdacdaaaxxxxxxbcbbacaaadbbcdaacbabbbdbbcxxxxbaxxcxxaaaxxaxxxaxaabdabaxdadxdbxdxxxcaxdbdxaxxdxabdddxxxxaxaxbaxxaxbbdacbbdaacadbddacbbaabbcbcbbaxdxxxbxbcbxbacbxbabcdaxbaabdxxbacacxxbacacbdacaddadacabdabdbdbbdaacdaadaddbdaabdadbdbaaacbaadacdbdxxxxadbxbadaaaaabaadbabddadacdacdacaaabdadadxcdbabdbddbcbadaabbaaaaccbbcbbacaddbcxbdxxxxaxdbxdaaabacxacxxaaaxacxxdxbxadxadacbdacbadbdadababbabaxxaxxbxaxacababxxbdadbaacbbdxbcdbxacaadaaaxxaaxdacxaxxabxbbdadacbacbdbdaacadaacxaaaaxdaaaxxdxabdaaxxcaxxaxxxdxbxxadaxaaadxxxcbcxxadbdbacdaacaaddbabdaabdbxxaadbcbdaaxxbdacxxxbdabaaaabbdaaabbadacbdabbcbaxxbcxxbbbdbdbadaadacbdadbddbdbcdbaadabcbacaabacbadbccbaaabdaaabxxdxaxxbdxbxxbacdbdxxdxabacxadbbbxaxcddaacdxdbdbaaxaxabdaxaxdxxxdacxxdabccxbdaxxxbcaxxxxaxcxaccaxxxbdxxbabaaxbddaabaaxdbxacdxxabbxxaxadbxdxbdadxbbaacdbddabacbdadbbcdaaacddadbdxadbaxxxdbaaaaacdxcdabxxaaxddxxxbbdaxxbaxdadaaabaddbddaabdabdbdaadbdabbbbdbbdababdacaadaaadbdbaaxaxacxxxacxxdaaxxbxxacxxaxdaxxbxxacxaxxaxxdxxxxdbaaxxxxxaxxdbbdaabacaadbdaddaaddaadaacdaaaaxaabaxdxxdxcaxaxbcxxadaxaxxdaabdbdaabbdbacbbdacabbbdacabdacbabaadbdaadaabaccdbbdbdaadaxaxxxbbadaaxadxacaaddbbdbccbadabaacbbacababaxdbbxbbxdabacdabdadbxxbxxabaxacddbbccxbxbabxxxdxbdaccxbbxxxxxxcadaxbcaxccxbdacxxaxxxadxbxaddxabaxxacaaaaaxdbxxdaaxbbadxdxxxxxbdbxxxdaabadbdbacadbddaababaaccbaabbabxaxxbcaxxxdbcdbaaaaaaaacbaaadabbdbbccbabcaaaaxxcdxxxaaadxaaxbxxaxxxxaxxbxcabaccdabadbdxbxxdaabxxcxxcxbxaxxdbaxcxxxdabxdabxxxxacadxxxxadxxxxxcbaaxxxbxxxacaadbxaxdbcdadaabdababcdbcadbaabxdaxxbxbcdaxxddxaxbxaxxdxcdbbbaaacadadbabadbabbdbaxaaxabaaabbcbadbbccbdbdbcaacbaaaaaxaxxbaxaxxxddxadxbdxaxxxxbaadbxxxbaxxbxdxaxdaxxxadbdxaaaabacbcddacbadadaadbdadacaddaaxaxxbaxdabaxcabxcxxcdxxbbacaaababbccabbcaaabadbabbbddbdxacdxdxxxxcaaxxacaacxaaaaxbbaxxbaadaaaxxdbxcxdxxxaxaadbcacaaxxaxxaxxdbxxxxdxxcdadaxabxbbbdbxdaxdaxxxxaxxdxbxdxdbdxxxxdacxxadaaaaaaacacbcdbabdcxcxcxadaxxxdaaxcabbbabbbdbacaacabdbbddadbabbbbdaddbbabadbcddbadaabxadbdaxaxdbaaabdacbaabaababaaaabbdbadbdbbaabadacacbxbxbxbaxxdbxbxaxcxaaxcxbaxxaaxxxdaaxxxxxxdxaxadbdbdxbxxxxddaxaabxbddaxxxaxddaxxaxxaaxaadaxxaxddxxaxxadxxaabaxbabxxxaadxbxxaaxaxaxxxdxaadadbaxbdacxaddxxcxxbxbxdxaaxaaxxdbbdxaadxaadxxxxbaadxxaabababxdbbdxbxxaxxbxbdaaxbaaaxxaxbaxbdbaadaxxxbaxxxbdbxxxxadxxbxbaaxbdbdaddbaacbbaadbbdbbdaaaaabadacaacdaacbaaadbdaadadadaaaaaacdbaabdbaaadadaaadadaaaaadabdbbdbacbabbaaaaabdacdbbbbaadbddacaadaxbbaaabcxaxxxdxxabxaacdaaaacbbabaxdxabxbbaabadbxxaxxxaxaabxxaxdadxdxdabaxxxxacxxxxdbdaddaacacdaaadabbdddbaaadabaaaaaxaaaxabxbdxabdaaaaaaacdadaaddaaadbbddbdaaadbbxaadxbabaxacxxabxxaxdxxadxdadxaxxbxbdxxabdaxxadaxbxxxxxaaxcbdacaxddbbxdaxbbdaxbdxaacxxaxxabdaabxxdxxxaacddbxbxaxcxbbxdadbcadbbabddbaaadaacadadxxxxxxaxaxxadbdaxxxbdadbadabadadbdbaacaaadbdabaacdbbdbbaaabbdxxbxaaaabcaaacbbbabcdacbbdaadaacdbbadbdaaaaaacdadabaacbbbdbbdbaaxdaaxbaxxxxbxcbdaxacdxacdbxxbxabaxaaxadbaxdbbxabxcaxbabxdxdabaaabdaacdbddbdbabcbxxabbxdbdbxxbcaaaxcbaxaxaaxbxxdacxaxxaacaadbxcxabdbcaxbcdxxacxxcxxbxaaabxxaaxabxcbxxxbxdbacxadxaaxxcbacxxxaaxaxcxaacaxxxxxdaxdabxadbxaxadxcbaaxaxcbaxxxxaxbbdbadaaabaacbcbdadaaacaddbaacbaxbaxddaababxxddxdbaxdxbxcdxxbxaacdbaabadacbbbdadbbadaacaabdaaadbcdbbacdaaacbadbbadaacddbacacbdbadadacdbaabccddbacadadacacdaxdxdxcxaxbxccbxbdxxxdaxxxdabdaacacdabadbaacdabaaddxaaxaadxxcaadbbccbacdababdbdaabdbbcdaaddaxxxbaxdxbdaxccdbxxcdaxxxadbxaxaxadaxaxbaxbxxdbaadxxaadaaaaacddbbadaaaaabdabbadadaaccdbdadaaabdacdaddacdabbccdaadxaaaadbabaaabaaababdbdbdbxxabxxxbxdxaaxxxcbdbxcxxacdxdxcxxaaxxaaxaabaaaabcbdbccbaadbacdaaabccbaaabbadacaacdabdaaaddadbdabdacaxxxdbaaaxbbxxxxxdaxdaxxbaaxaxxdaaxxxaxdbaaaxadxacxxaxxxbaxxbxdxxxdxcdbaaabacacddaadaacacdaxabddaxbxaxbxaaddbdxcdxbbdabxdaadxxxxxaacbaxadxxdxxaxxaxxadxbxbcxxaadxaxxxadbadbadbcbaabdaabacaaacabddbbaxcaxxabdacadxaxacxxxdaxdbxxaadxxbxdxcxabbdxxaxxxbxxddxdaaaaababdaadbbdaadbbbaaaadaxaxaxxxdbbbxxxxdxxcxccbddbabdbdbacdadacaaaadbaaacxxdxaxxdxaabdbcdxxbxaaaxcabxabdaadaaaaaacbdbaacddadbbaadadaxxdxcxcacaaaaabcaaabbdaacdaaaabaaccacdbdadbxaaadxdaxxcxaxbxaxdaccbbcbdbadaabacaadaadacbabdacxxxbbaccxxxxbdxxaxacaadxxxddaxccxxaacxxbabxaxadxxxabxcxdxbabbxbxaaaxxdbdadaxcxxdbaxxxaaaaxabxbbxxxaacxxdxbabxbxdaxbxaxbdbxabdbxxxxxxxbxxdbadbaddxxacabaaadaaaacbcdaaabaaaddaaadacbadbdacbdaaaaadaadbbbdxaxxbcaxbxaxadaxaxbdbbaadxdaaaxaacxxxaxdxaxbxaaaxxacxbaxdbbddxdaxxdbxxxaabcdaxaxbxdxxaxxbdaccbxadbaaaaxbxaxadxaxbdxbdbddacaxxaxdabaxaxxbbxddxdacabdbdbacdaaaaabbdabacaacbaadbxdxddaababbbabdbacdbcccbdadaadaaxcxxaxxadxaaaxcbabcxbbbdxxabaaxaxxddaxcbacxxxaxxxabacxcxdxcdbaxbcdbacbdxdxaabxadaacacbabaabddbadbdbdbcxxbdaxxabxacdxxxcxdxxbxxbxacxaaacbacxacxcdxxbdbdbadxbxxaabbxcxbaaaacxxxxxcbxxxbdabacdbddadbcbdbaabaacaaacaaaacdbdbdbxxxdadaxbabcaddbdadacaabcacdbabbadddbacabaaadaadxxbdxcbaxadbaxxbbdxxbadaxadaaxdacxbxxxxxdxxxxbxxaadbbabbaacdacbbdbaadbdadbxaxxxbxabaxxxaabaabbdbacbdacdacdbccdaxdbdbxcxxxdbxadxxadxaxxadxaxxaxacxxdxbdbabacdbaaabbacbaacdbdaccdaaaacccadadacaaaaxxacxxxbxbdxxaadacxcdabxbxxxxxdxdxaaabcdaaaabxbaaxbadabdaxbxxaxxadxbxaaddaacaacdadacdacaacbabaabdbbacdbabbxdxxbdaabddxaxaxadxdxdxxdadbaxbbdaaxcxxxaxabdaabdbaadxabaxxaaxdxxadbcxxaaxbaxxxabxbxaxxabaxxxxxadxbxaxacxdaaaadxaaabddbbxbxaabdxxxabxcdxxaaxxxaaxadaxdbcxbbdxxxbxabbaaxbacbccbadbadbadbaadbadacbbdaadxaabxdaaxaadxbxxdaacbacddbbdbadbaddbbbbddaabdbbbdbadbbadbbxdadaddacaxbdaaxdaxddaaaccaaaxaxxaxdacbdacdaaabbaacbccddaabxxxxxabbaaxaxcdxxxbxaxbaxxxaxbaaxdbxbxxacaxbaxdxaxxacbdxdxaabxdxxxxaxbbbbxcadbxbabcbdabdabdabdbbbdbbcdbabxxxaxaadabdbbdbbadbaaacbbxdbadadxbxxxcaabdxbcdaxaxaxxacxxbdaxbxcdbxcxaxxaxxbdbbdxxaxbdabbbbxaacxxbxbxbxdxxbxbaxbdxaaxbxcxbcdbdbxbxacaadxaabbdbdbaacabaaacaacbaadbddbbccxaaxacadbxxxbadxbadaxdaxxcxxxxbaabbdaabaabdbbbadabadbdbbadabbacdaaaaabaadaabaxcdabaxxxxadabcdddababaabdbaxbdaxcabxxdxxbxbaxdabxaadbxdaaxxxabdbaaacdacdababadbaaadbcbcxdxxcxcbaaaxxaaaacbaaxdbaxxbaxacdaxxaxbbbdbdababcdbcccaaddbdxxaxxaxxxxxxxdxxdaxbdaxacxxxbxxacbaxcxaacdbdacdabdbbdabdbcbcdabaccbdaaabdxaxxadxbxxadaxabxaabxdxdaxccdaabdaaadacdbabbdbbbacdaaaaxxdxdxaxdxaacbdaxxxaaxbabxxxbxabxbxxdxdbxxxxdxdxdacbbxbxxacaadbdbbacxxxxdadxxaaxadxxaaababaadbaadbxbxxxdxbaxbxaxacdbacxxxbbaacbxxaaxddxcbbxbxbxaacbcdaacddaabbcdbdbbdacadaaaxxddxdxdaxbbxxaxxccbxaaxbabbaxbdbabxxbdbdbadxxdxxaxdbxccdadacdadaxxbaaxbadbaadbdbdacaadacabdaaaadbbaxxaxbxxaxaadxaxxdxdbbbdxxxxaabdxcaaaaxxadabaaabdbbddbdabbaaaxabdxcaxdaxxbaaxxxdaaaaabbaaaabbdacdacccaabbbdbadbcdaacdadaccxaxxxaaxbxxacdxdbxxbxddaxdaabbdbaaaaaaadaadadacdaaxxxadacbxxbxcaxaaaabaxcxxaaaaxcdxbacxdxxxxdacdbacdacdbabcdbcbadaaccaxxdbxxxbbxaddbacababxxxadaxxxxxxaxxxadxxxbbxdxaaxdxbxdbxadbaabxbdxxcbcxacxdaxxxcxababxxxabxxbxcaaaxxaxdbbxdbdxaxxaxxxcxbdaxbaxxxaaaxaaxdbaxxxxacbaaaxaxbaaxcxxbxxxabbxxxdbdbabbdbdacabbdaacdbcadaaadabdaxxabxxaxxdxxxcaxbxxadaabxxaaxxbbxaaxabbbxdxxxxxxababxacdacdaaabxdxxxddaddxacdaaaaaaaadaaxaxxxadbdaxcdbxxcdxdxxxxxcbaadbddabxcadbxxbxbxcacdacccbdbddbdbaadadbdbdbacbacxaadbaaacdadaabbadabaaabdabdbdbadacdadaacdbacbbccbadbabdaccaaabacccacxaacxadxxacbabxxxdxxcxdabaaxbxdbabadadbadbaaabdabbcadxxdbaadbdxbxxxbabbbxbbbxaacddxxadaaxbdbxbabxaacxbacxbdxaxxdaxaxaadbbcxxbxaxaxaaddbdbdbbabdadbbacbaababdbaaaaacdbbcaaaacdabaaadbaaacbdbdbbxxxcxbaaxxxxaxcdaaaabxxbadxbcabacdbdbdabbaacbcbdbabxdaaaaaaxxxdaxbaacxbaxxxadxxbxxaxxxdxaxbxxxxaadadxxxaaxdacaabdadbabbcdbacbacdbaaxxdxbxxxbxxdaacxdaxbbxaaxbbxxxdacxaaacbcdaaadaabdbacadaabbbbdadacaaccabdabbdaaaaaadaadbacbaadaadacadbacbacxcxaxaaaxcxxcdbxxaxxxddbdxcaxaddaxxaxxxcbxbdxxaxaaaxdxxxxbxxxdaaadaabdxxxbadbdaxdaaaxxbdbxbaxcacxxbaxabaxxxaababdbaaadbabacaacbdadaxbxxaaxxxaxddabadbbaabbdacadadaaadbbdbxxbxdbdxxabbaaxxcbabccaaacdaaaabdbbbbcbaxxaacxcxxaxaaaxcxcbxacxxcxdaxdabbddbdbaacbacadabdxdaddaxxaxxadbaxadaxxaxbbcaxaabaxxddxdbdbxbaaaxaxcxdaxxxbdaaxxxaaaxbcbxxaaxxbxxxxcxabacabdxxdaaaxaabdaddxadxxaxaaxxxabaadaaaadaaadbdddbabcabcababadaxxxbaaababxdxaxaxaaxbxaaxdxxbaxbdacxxabxddabadxxxababdbxxxbxxcxbbbxaaaxxaxddxaxbdxxaxxadacbcdbbabaacaacbcaacbbabdaaxxdxdacadxcxbaacxxbdxxxxdbxbxabdxbxbxxxxdaxxxadaxbbaacbdbbdabacddbadbddabaacdabaadabbaabaaxxbaxaxxaaxxxxxbaadabdbdbdbbdaaabdacdxxxaadxxaxbaxxxbaaxxxdxxbxaaaxcxxxxaadxcxxdbxbaxaaxbxxaxadacdxbxaxcbcbaababcdacacaabbabdbcbaabaxbbaxxxabcxxabacaxdxxbaacaxxbabaadaxdxxxcxxbaxccaxbxabdxacxcdbcadbddbcbdacddbddaxaxbxdbxaxcxxdbxaxdbadxxdxxdbxadxxxabdaacdbabdxcbcacbdbbxddxbxxdaabbaccbbaacabcdbdacacdbaaacadbdbbadbdaadbabaaaadbaddbadacdxdxbxaxaxxbaxbbxbxdabcbadbxxaabadaadbxdacxxaadxdaadaxadxxxxdxxxbacxxaadxdxbxxbdxaaaaxcdaaabxxxabdbaaxbdxaxxdxxxxaxbcaadaxxxacdbacaaaabdaacacbabbddabbdaabdbdaaaxbabadadacdaxaxdadbbxaxacbaadabadbdbaadbdaaabbdabbbaaaxaxxcxxaxdxxacaaxxxxxdxcxxadxaxdbxaxaaxaxaxdbaaabxxxxdbbdbaadbaadbaaadabdbdbdbaadbbabxdabbdbxxadxadbdaacaaaadbdaaaaabbdbxbxbxxbaaxxaxxxbaaabxbxaaaxcxxbxbddaacxacbbdacaaadaacaababxxcdxdabxcddaxxxbaxdxdxbxxcacxxbaxbacxdxaxxxxaxxbaxxaxxxxbaaxacxcdbaxxbcbaxxcaxbdabxadxxxdxxxdaaaabxxaxcaxdxdxabxdxcxxaxadxcxaxxddaxabbbbbxxxabaxxcxxxxxaxadaxbdbxbcdxacxadbxxxadxcddaxacxxxxadxxadbxxaadxxcaxxaxxxxabbxbxxaxbxaaxcxaxdaxxdaxxabaaxxxcxxaxbacaacxxdxadxxcaxxxaxbdadbaabbaabaabdabdbdadbacbaaabbdaaaaadbcbdbaadbaabaadbababbdbdbdadadacacdbbabadadacaaadaaacadadxxaxxxxxbaxxaxbdxaccxxaxxdbaaxaadxacxxdaaaxxaxxdxxxbdbxxadxaxadxxbdaaabbaaadaddacbdbbdbaacadaacbbcbaxxbbaxdaxaaxxxxdxxaxdbaaaaaxxacxdxxxxdxxbxxxdbbaxxacdaxxaaaxdbdaaaaacbdaaabddddaaacaaacaxadxxxxcdxxabxaaxxcxxaaaxbxdbcxxxaxbbadadabdaabaaadbdbcaccbabdbaabaadabaaabdaacaabacadadadaacdbadabbabdaaaaacbdbdbcdbdaxxdbbbxaxxadaacxxacxadaxdacxbxxxxxcbdxxxxcxxxxabdxdxaxxbdxxaaaaxbxxxxxaaaabdabadbdaaaadbcabdaadbbxxabxxcbdadbcabbdaadadbaacacbcacdabbbcbaxbxxdaaaxaxcccaxaaxabdbbdaacadbddaadabbabbdbcbbbaabadbbabcbdxaxxaxadxbdbaadbaccbdbacadbbbdbdabdaaccdbbdxbdbxabaxaxbxdxxxxddxxcabdxxaaaddbddabbaabbaacdbdbaaacbbcaxcadxaacxdxacbabbbdbabacaacaaddadabbabdbaaadabadbaaaabcbaadaccbabdbaaaacdadbdbdbxbabcbxdxxcaaaxaaxdbxxaxadxxxxxaaxaaxxbacacacdadacdacdbabacbadaabbcbdaacaaabxabbcbacbbcaaadacbdaadbaababcbbbdadacdbdbdbbdabbabaaacbdadbacdaacaabaadxxxbdxaadxdadxbaxxdxdaxbdadadaacaaadadbdabcbbacabbcabdaaaccdaaxbxdaccxxdxdxbxxdaxaxxbabdbxxxbcbbxxxxxbdaxcxxxbdaxcxbadxxxaxxdxadxaaxdxxxxbbaxxxbxcxbxaxxxbxddxabaxaxxxdxaaxxxxaaxcaaxxaddbaccxaxbdbxxxdxaxacxxxdbdxdbcdxaxcdabxcdaacdadxxdxbabxaaxabcbdacbaaxcdbacaaccbacaabcbacbacbaadbdadacbddbaxcbabbacdabdbcdbbadbcdaacdaaaaacxbcbxxdxxbbdxbaxacxxxxccdxxxacxbxxacxxxaadaxxcadxxdaxbcbabacxaxbdxxxbxxxbdaxaxdaaxxxbxaccadbdabbbbcddaaaadbaadabaaababxacaxxdbadxxaxbaxxxadabdaxacdaaabbabacaadbadadbdacbaddacbdxxdbxxcbxcxbadaxcxxaxxbbaacaxbxxxbacdadxxdxcxxadaaxcbxbaxxaxaxaxxdbxxxxxdxadaxacxaaaaaabaaxxxxaaxcddbdacxaxaxxaaaxcadxaxxxxaxaadxxbadbxxadacxaaxbcdadxbxbxxaxxbbadaacababcadbaabdabcdbbcdabdabcdaacbcaxbabdxcdbaaaaacdddaabcbbacbaadadbadadaacbdbbddbaabxdabxacxadxaacdbbbadadxbaxxaxxcxxxbacaaddaddaabaabaacbdabbbdabccdaaacbcbdbdbabbadaaacbabaddxadaaxaxbxdxxbdbxdabacbabxbxxbxxxbaxxaaacxcxddabaaxxaxadabxdxadbdbabxbxbacbadaabadabdabdbdadbadaacxxdxxbadabaddaxbbxbxxaacxbxxaxxabdxxxxbdxxbaaaxbddxcbxxxdbaaaxbdxxxxxbaxacxxbxbxxaxaaxxbxaxxdaaxaaxabaadbdacaabaacdbcabacbdxxdaxxcadaxxxxxdaxxadbxaxaxabdxadxcabaxcxxacdadbbxxdaxdxxxaxcdxxbdxxxcaxxdxabxaacxcbbxacbbddacbbdxaxabdxxxxbddaxxaxbadbacdaabbacbaaaadabddacdadbdbbaxxbxxbabxxxbxxdaabacdbdadbdbdacacddadbbbbabaadbacbddadadxxxabbxxxxxbxxxccaadbxxxdaxcdxcdadxbxxabxdbcaxaxxaxxxaaxxdbdacaccaabaabadaaddbbaaabdacccdddaaabbbadaabadacxxaxaxdxddbaaddbaabdadaadbaccbdbdbdbaaabcacaacabadbdabdabcbacxcacdxxxxbdbxxabxadacxxbaxxaxxxbddaddddaacdabdaaacdbbdbcdacaxaxxxxbdxxdxxdaxbbdxbxxbxdaacdxabdxadaaxxxxdxacbxdbdaxbbdbaabxaxabbdaxacxxbxdaxxxxbaaddaccaddacbdbdbbdadbaabbbaccbbdbdbbdaxaxcbxxcxxaabdaacdabxaddaaxaaadbxxaxadabbaxxaxxbxdaadbxbdaaacdaxdxdaaxxaxxxccxbcxbxabdxbacbcxxxaxxbxxbxccbabbccabbdbdacbbaabbbaadaccaddbdbaxabxcbdbbxbbxdaxbxbadaxcaxxxaabbxbaaxaxcbxxxadaxxxxadbxaxxdaxxxbbxxbcxbxbxaaxxbxxxxdbdxaddabaxxaaabaadaacabaaabbacabaaaabaacbaaaaxbacxxaadxdxbdxxxxaabxdaaxdbabaaaxxbdbaxaxbxbacaxxbdadaadacbdbcacbaccaaaaddaacbbadddacadxxdaxaaadbxxdaabacbcdbabaaaaabbadabbddaaaabdbacaxdaccdbacabaadacadbdacbdbdbbadadxdaxdxaxdxcbdxaxaabddbacbadbbcbaaacbcbaddabacxxxxdaxxdbxacxbcxxxaxxxxaaaxxdxdabadaxxxxbxaaxdxbbxxxaacaxdxxabbbbdxcbdaabadaaacdaaaccbacbaxaaabdbbdaaddaacacbbaadadbdbbbaaadacxabxbadxacaxxcxxaaaxxadxbaaddaaaxxxxxxdxxbbcbxaxdabaxxabacxaxxxcaaxcxdbxxaxacdaxbdbdbdaacdaacdadaaabdaaaacbaabaxxdbbxxxxdacbdaadadaaacabdbccddabbdaacbdadbacdaadacdbxaxxcdabxxxxxddacxdacdbxxccxxccxddxaacaaddacadxaxbaacbaxxdxaxxdbbcdxdacxxdxacxxaabbdxbdxcaxxxdaxacxaxadxdaadxxaxdxxxbdbbdaadbdaacbaaabdbdbababbadaaadbdababbdxbdxxdbaacaxxxdbdxbabaxcdaabdxxaxbdxaxbdbdxabacxxbxdbxaxbaxbdaxxxaxcxdxxxadbxaaxdxxdxxbdaxxxxcxddacdaddadaaacabbdababdaaaadbdaaaaabdbaaacadadaacdaadbdaaaccaaadbddaccxdxdxxbdbdbacxdbxadbbxxxxxxcdbxaaaaaxbdxbaxxxdbdxxxbdbdbxxcbxcdacbcbxcxaxxxbxxdbxacxxaxaxbxxcdbbxxbaaxcxxabaaxbaccaddaabbcaacdadbdbadbbabaaaddbacbdaxxadadxxxbdxxxxxaaadbxxxaxxxaadadabaaxxbxxacbcxxaxdxcbdbxbdxxaacaaaaadaacbaaabdabdbdbbxbxaaacxxxxacxxcbxdxxxcdxadxbabcdaxbxxaxadxdbacxxdxxxdxaaacdaxbxxbxacxdxcdbaacaaaabddbababacabaacxacbbcbxbxxabxxaadacdbaccdadbcaaabcdbdbbbxaxbcxbbxxxaaaxdxdddaxaacxbdxcxaaxxaabxxaaxxaabxdxxbxbxxaxbabacdababbcdaaabdbbddacbdxxadaxaaddacbbdacabaaacababdabdbdadacxbxdaxxxxbdaaxbadxcbdxaxxacbxxbxaxccxxcxbxaxxcxbdaabadbdbbacaaadbaabcdadddbbaacdbadabcbdadacbbaadxdbbdaxxcdbaxaaaccdxxbaxxxdxccadabadadbdaxxbxaxaxaadbdxxaabxxabdabxxxdbadbbxxbxxccxxbxxdxxxbdxacxbxxxcdxccxxxxbbacbaxbxbbaxaxxxaabaxxabaxadabdbaaaacddaaadbbbddabadabxxbxxaxxxabxadaxdbbxbaxxbxaxxaxabdaaxdxxaxaadacbacabdbdabaaadbdabcbadbbbacbdbaabcaaabaaaadaadaccdbcdbbcdbxxxxaadaxdaxdacabdbaabdaacdbaddbaaaacaadacbacxaabcdabdacbaacddbabxxdaxcaxbbxxcaxbdbxxaxbadacdaacbcdaababdabaacaacxcxdxxaxxacbxadaaacaxxxbdaaxaaxxcaxxaxaadaxdaxbxxbxxxxxxbxxxcdxcdbbxbxxaxbxxaxxcaadxxdbxxxbdxacdxdbddbcxxbcaacbbaabadbbbdaabdbdbdacdaabbaaadbdaxacdxcaaxaxbxxxxaxadxadbdabdadacbdadbaacdbadbdbacdbacacabadadadadbabaaacbxxxaaadxbbcbxaxaxdbadaddbdacdbadbcdbaaacbbxxcxxxxdadbxaxacxxcxxaaxxxcxabaxacxabdaxaaaxbxxdxxxadxxbcacxbdxdxbbxaaaccdxxadbxbxaxdxdxdaacaxaxxdxabdxxaaaaxxcxxbacxxxadbxaddbxbdbacdbcacdabbdbdbdbdaxcxabaacdadaadaadbdaadbdbddbadbcbbbbdbcxxxbxaxxxxaaxbxxbxaxbbcaaaaaxxcxbacbxbaaacdaacbbaaabacbbacdbacbbaacbdaaaxdxxxbxcdbaaxddacaxdabcdadaxxdxbbaabbxdbacbaddabaadaaadaadabadbdbabdaabaacbdbxxxdxxaddbbxbaxdxcxxbaxbxdxaxaxaxabcbdbddbabbadbacbabxxadaaaxxxbddxbddxdxbxxaxdxxxabxaxbaxadacxbbxaacxxaxxdxdaaxbxaadxabxbaaxaadxxxxxbdbcbbbxxxaaxxxxabdbdbxdxxxxdxxbaaxxxxxadaaaadaaabbcdbacaacaaaadbadbcbbbcacdbdacadbadbacaadaccdabxxcxxdxdxxaaxaabaxaxabbxbxxxxaaaxxaddxxxxxdaaadxxbxbdadabdxxccxxxabdxxdacbdacaadbabbaadbdbabdabaccdxxxacxaaacbaabbdaaadbaccdbadbbdbaxaxabdaaaxxdbbxxxxxxaaxdadbadaaaddacbdbdabccaadbbdbadaaaadaccbcbacaabcabxxbxxaxxbabaxaxaxxxxxbxacbxdbbdbdbcbacdbbacbaaccabddxbcxxcxaxxcxdacdbxxbxxaxaadaxxxxxaxdxxcacxxxacbabxbcbbdabaxdadxbxdaxxdbxaxdaxxacadacxaaxxxxaaccdxdxabaaacdbbdbdadaabbdaaxbdxdxxdbbdxdbadaacdadaaaacbdbaadbadbadadbdacbabdaxaxcbaaxxbaxdaxdxbaxxxxaaaxbdaxdbxxxbxcdbbaabdbbacbbaaacaacdaacbacbcdbdbcadadaadbabbdbabxxbxxababxabadxaxdbaxadbxxxxxbxxxxbxxacbdbxxcxxxxdbaadbaxbaxaxbxxxxaxadaabaxaxdxbbxbcxxbxxxaxbxacbdaxxxcxxdxxxbxacbbxbxxxcxxxxbbbdxxbcaaabxbxxaxxxxxbdaxbaxxxxacbxddxcdacdbdbabaxbacbaxaacdbaaabadbabbdbddbxxxacbdxxaabxacbcaxxxdbdacdbxdbxxxcxxbxdaccbadaacbdaacaaddaabadbdbababaabbxxabaabxbxaxxaxaaabaababxbdxaxaxdaaxxadxdadxxxxdaxxxadxdacxxdaaxdxdxaxxcabaaxxaaaaaxbxbdbaxxadacbcbdbbacdbabaabdadxxxxbccxbaaaxbxxccbdbcbaxxbaxxxxaxbcbcxxaxxaxaxxacdbxadbbxcxdxaxxdxxcbbbxbxaxxxcaacacaabacdbdbacbaxaabdbxbadbxcdxabdaxaaxcaxxaxbxbaxcdxxxaxxxxaxxxxdacxxaaxcdbaxxbdaaxdxbabdxadacxxaxxdbdxaxxabbxxacxxbxdaxxacxxxbaxxbxxaxbxbadxccaxaxxxbxaddaxbxaxxdaacaaxxaxdbaxbaaxacbddxaxxaxdbxadxaaxcdaxxbaaaxaxxabcaxxbcxdxdabxabbababdadacdxxaaaxxdxbdxaxxxbxxxxacdxxacbxxaaxcaxaxbxacccacadaaabdadbdabddbbbaaaxxxbxacdxbxxxxxxcxbxacxxxcbxabaxaxccbdbacbaabbadadbbacbbdabdabacacbdbddbabaabbdaadxaxaxaaxacxxaxxxxddadbxaaxaabdbddbaxcbaaabadadddbabbbdaabddbabacbaaaabaabbaacabxxdadaxbdbxxaxxbaadxxdxdaxxbxcaaaaxxaxxxxddbxbaacaadaxxxaacacxcdxcbabbxxxaxxxdaxabcxxabaadbaaaacdbdbbaacadabaabxcbbxxxbxxxxddxbcxxxxbxdxaxcxxxaxxadxxcxbcaxcxadaxdaxxdbcxxbaxaxcbacdxxxaxbxxbcxxdxaxxaxxbacxxbxbaabccabdababbbaaaabbcaadbdbbacabacbbdacbabcbaccaaaxbbxbdaxdaabxxxxaxcbdxaxbxxbxxbxxadaaxdxcdaaadbdabbabaabbdabdbaccdaadbadacdbcdacdacabdbaacadbaaacbadadbddaccdbdaaababadxaxabdxxxxcaxaaxxcxxxabaxabxxbaaaxaxxacdaacbxbaaxxxddbbaaxdaxxdxacdbaxxacbddabbbabdaxxcdbxxbdaaxxcdaxxxabxxxxadbdabxxaxxbcdxcxbxcbdxxxaabddbdaccadababdadbddbccaxxdbdbadxaxbaxxaxaaaaxdbxxacdaadabaaccbdacacdbadbdaddxxxdaabadaxxaaxxxdbaaaxaaxxcxxbxdbaabxaxxxxbabdxxxcxaaxbxdxcdxxxxdxaacaaxcbdaaxxxxaxaaadxxaaaxxxxxxbaddaxacxadbacdbaxbbxabxaxdxdbdxbaxcxbdbaabxxxxaxcaacaxxxxccbaxdaadbdxxaxbxxaadbxxxaxaxxdacxadbbxxaxdxdadadbddaadaacbbacacaaadacbabadaadbcacdbcdacadadbabadadbadbdbcdbcdaaadbdbdbxxxxabaxabdxbacaxbaxdxxbcxxbxxaxcxxcxbaxaabxxdadbaacdadacbabbdabaabadbadadaaaacxacxxxxxdxdabxxdxaxxbbdxbbxcdxababaxbbxaaxdxbxxxbaabaaabcacdaacaacdaaabaaaaacxaxxbxaaxxxbxbxxabaxxcbabdxadabbxxdbcxxbbxaadxbdbdxxcdaxacxcbdxadaxxaxxdxdxxaaacxxcdacbbxadbaccdadaaacaddbaaaxbcdbxcbacbxxbbxxbxabxbbxcxxbadxdaabxbbxxbaxadaxaxdaacbxxcxcxxabaxxbxaxaxaadbxxaxcdxabdacbxabadaxxxaxaxxxxxdaxcadaaacdbxxaxxbxdxdaxadbxbxxxxxxbaxdxxxabbxxxcxxdxaxbacdbababdbdaaabadbdbabcdbbxdxxbxxxxdabbadxaxxdbbdbdbaaacabcaabbaabbacdbcbxxbxbaxxaxababdaxbxxxbxdxbxaaaxxabaadbbabbabbaddaacbbaacdbdbdbdaaaxxxbaxaxdxxbxxxxbxaacbaabdaaaabadbdaadbaacdaacxaaaxdaabdaccbxcaxdaxxxxxdaabdaddadaaaaaacbdbdabadbcbdadaxxxxxcxaccbddaabadabaadbadaadbxbxbxxxcaxxabaaaaxxadxaaacacxaaxxxaaaaadaddaxdxxxaxxcxacaxdbxbacaaxadaxbdxxxaxbxxabxxaxbabdxdaxdbaaxxxaadabxxaaxdacacdbcbcaaaabdaabdbdaaabdacdaaacbxdxxbbxdbxdxbaxbdxacxdxbxxxxbdaacbdabbdbdadaadbcbbdadbabxxdadbxabxxaxxaxbabbcxaaxxbbbxaabaxxaabaaaxxxxaxbaaxxxbbaaacaxxxxxxdadbaaxaxbxbxxxaxxaadadxxbdbdbdadbadabbabdbabaddbdaaaabaadbxxxdxxxxdbbacdacddbdababbaaacdaabdaaaaxacacxbdbdbcadadbaaadbadbbadbdadaxxdaxcbxxxaxxbbbaabaabaddadaaaacaabbadacabdbabdabacbdadabaccddacdadbacdadaadbadaadbdaabbdaaacdxbxaadaaaxxacdbcxxxaxdaaaaaabbdbdbdadaacbbdxbcxxaxbxbacaxcxdxxbaxaaaxxcdaaacaxaxdxdxddxaaxxxxxxaaxxbaxcbxaxbxdbacxaabxxxxadaacbbaaaaaacabacabbcdaaaaacadxdaxabbcacbbabdddbaaadabadacacabxaxxaaxaxcbbxaxaaxaxxxbaxdxxaxaabxcaxabbdxxxabxbddbbbaabaaaaabdbaabaadaxxadbdxadxbxxcadxcaxcbxcabbaaabbxxxxbabxbddxbbxxacbxaxxxbxbxcxxxaxaaxaxdaxdxxaaxaadabxxaxxaxxxacbadabaxcaacdxacaxdbaaacbbbaaadbcccaaadacdbcxaxbbdbaxxxbxcbaxbxxaabaxcxaaaadxxdaxbxaxaxxadacdaaddbacdaccdaaccadadbdabdabxaacxxcbdxaxxdaxbabaaxxadxacbcxabxaxxxdbacaaadabbbadaaaadabacbxcdaddadbxxxdacxdbxbxaaxaxbcdxxaxaxbaxxdxaxccadxacabaaccbdadaadbaccdaabxxxxxbxadbacxxxxaxacbacxxbdxbdaacdaadaadabdbbaadbdaaaaaaaadbaxadaxabaaxbcdbababdaacdaaacbaaabaaaccbddbcabadaacbdadabaaacdbabdabbacdaadadaacxddaaacabdxbxxxaaxacdadxaaxxxaxxdxbaxacbbaxxxbxdadbadbdbcadbadbdbbadbaddadbacacbaadbaxxdxdbcdbxbxdadxaxacbacaacdbacdaddadbabcdxcxacxxbaaaabbxbbcabxxaxdaxbabxdadbbdabbaxdbxdxbabbdbxxxxxbbaxdxxaaxcdbxdbxaaaccbcdddbbcdbddbaadbdacdxaxabacxdxadadaaddbacaaabddaabadaabdddbaabdbddaxxdxxbacbxxaxbxxaxaxxxxabaaabxxxaxbaadabcbcaxbdxcdbxaaxbaxcdaadaaacbdbdbcdbadaacaadxaxdbaxcbacadbdxaxxaxaaaaxxaddbaacacaddaabcdabdacdacbbdbbaaaaaddbadbdacdaxxbdbdxaxcxabbbdxdxdxbxdxcbaxaaxbxdbaabxxxdxbxbdaabxadaxaaxbaxbaxaxxdxaxxadbxxbbxabcxdxxaxxaaxbcaxaxdaxcxxaxxxbaaadbabbacxdxacxbcaxxxxxadxaxacxxaaaaxxdaadbdxcxxacdbcxacxaxbaaxbdxadabbxxaxxbxdxaxxaxaaaaaaacbabbcbbabaadacbabbabdbbdaaxxcxdxdaabxxdbaacxaxacaaxxdxbaxxaaadbcdabacdbacdacaabcbxdbxdaxxbxaaaaxacdadxcdbxdaxxdaxbadaxaddxxxxxaxadxacxbdaaxaxxaaxaxdxxxxcxdbaccbbadabdacbacacdaaadbbcbddabbdbdbaaabddbaabdbaccdaaxcadaxdxaxxddacxaxcxxxxdxbdaxxxacxxbdbxbxaaxabdxbbcacabdbbbaaadabdaaabacaaadxxdaxxxxaxdaxbabxdbdbbxaxxacaadacxaaaxaaddxaxdxcbxdaxaaxaaxaxaxxaxxxdxdxxaxxdxxxaxdxadaxxxxaxdbcabxxxcaaxaxxdxxxxxaaxaxxxxxaaacxadxcbxaxxcxxxbbxxdxxacbaacdxadxxacaaadxbaaaxaxxxaaxxaxxdaacxdbdbddadbxaxacxdxaxddbcaaaxdbaxaxcdxxxbxbabdaaabbadabbbdbbdaabdadaadabaxcxaxdxabdbdaacdbxdbdaadbddbdaaadbbcdaaabacadbacbbdxabadxxbaxbcdbbacbdbdacabdabbbbacaxaaxxxxdaadbabbbabaadbdbbddaadabcbabdadbddaxxxbxbxxxxxcdxaxxccaaaxcdaacdbbabaacbcdacdaacxbxbaxbbcbxdxxxxaxacxaxxacacbaxdxxcxaaxdxbdbxddxxxxbdbxcadbxxdaacdbcbadacbdacbaaacbbcaaadaadabbbdadxxbbcaxaxbbcxxxdaxbbxxadxaxacaaacxaaxxdaxxacxbabdaaccdacbbaaaaaaacbcddaxxxcxbbxbaaaaxcbcaaxbdabxaccxbdbxxacaxbxxaabdbbaaxcdbaxbxbacbbxaacbbaacaxxxxxbacabdadacdbbaaacdabbacdabadabadbaaaadxaaaaxbxcxxaxcxbaxbbxxbxxxxxabaxxdxbxxbaxcbaxxxbdaxxxcbacaadbcbbdaaccdbdaxaxadxxxxbxabcxabddxaxxcxxdbxxaaaxxxxdxaaxxaxbxaxbxdxxbxbxacxdxxbcdaddbdbabadbbacbaadbddadaabxacbabaxbxacbxbaddbxxaxxaxabdbaxaxxabxbxdxcabxacxxxcxbbcdaaadacbadaaaddbdbadbaxaaaxcbaxxacxbdaaxxabxbaaaxcxbbaadbbbcxaxxcxaxdaaaaaaxxbdaddbacbbadaadbacbaaddaaxcaxaxaxcxaaacaabaaabbdbdabdbabacdacadadaacdbcbacacadxxxxcdxxbabxaxaaxxxxbxdbaxaxxxdxxaxbxdaxcdbxaxxxxdxaaxbacbaxdbaaaxcdxxaxxxxbcbxxxxadaxxabcdbcabadbaacbdaaacbdxcxxaxxdaxxxbabxabacdbdabxxbdxadbbbacxabbxxbxxbxadbxaaxxdabxdaxxbcaaaxbxddabxxxaadbacxcaaxxadadxbaxxacbbdxbbbxcdadaxadxaxxcxcddadbdadxaxxbaxbdxcxdbxbdbxxxxbbbdxxxbbcdbxxddbxcbxxdaxxbbxaxxxxxaxacdxaxaxaxxbbdbbaxbaxbdbxabdxaxxaaaaxcbxxdbbdacbabxxbxbdaxbxdxxbxaxdxcaacdaadabadbdacabdacdabdaadbxaxdaxacbaxcadxdbxxxaxbaxcxxabbxxbdxdbdabbxdxxxbxxadbbxcxabcxxdxacacxxbdbbccxbabcxbxxdabdadacabcadaaaaaacbdbcbcdaaaaaaabbxaxxxaxxaxbdbaadbdaaaabbabdbddabdaaababdaabdabacdbbdacacadbbdaacbaacdaxxdbbbdaabbbccbacbdaacdaadaaabdbxxdbxaxaxdxaxxxbxcdxxbxbbbxadxdxaxabxxcdbxacbbcxdbcbxdbaxxabdxbabdacacbbacbacdbaabdaxbbxdbaxxxacxxxxxxxadbdxxxxxbbacabcdbdaxxxaxadaxxcxxdaxxbxxcbdacbcdaaabdacabdbbacaaccddxbaxcaxxxdxdxxxacxxxaxxxaxcbxxxaxdxxabxxxaacdbxdxxabdbxabxbxxxdaxxdaxbaxaacbbdbacbdbdbdbdbaadaaacabdadaacbxxcdxxxdbxcdbcxxdxxaxxxbxaxxdacbxacxxccxacaxxbdxxxaxcdaxxbxaacbaadbabdabcbaaabadbabdbabbaaaaacbddadabdbdaacdaxxaxxdbxdaxaxxxxxaacxxxdaaxdabdbxxaxaxbxaaaxdbcaxcbaxxdxxadaxxaaxxaxbxxaaadaabaccacdbbadbbcdaaaabaababadaabdabaxabbcxadxxabxcdaabdaacaccdbdabcdadacxcbabaxaxxabadxxdxxaxbdacaxxxdxacxxcbdxxcxbxbaxxxxxxxxaxbaabxxacaxabcdaaadbddaabaabaababxxbxcaaaxxbxaacaxxxdxaxxaxxaxdbxacxxdacaxxdabxcxdxaxaxxadbdxxxxbxcadxcaaxxaacxaxxxbxbxxbadxaadbxcxxxbaxcxbcxccxdaaaaxbaxxxxdadabxxxdaxaxcdxxaacbbacbaaaaaabaaabbdbaacaadbdbdbbaacdbaxbbbdbdadaaabdadacbccacdaxacxxbxxadxbxxacaxdaxaddaxxxxabbcxxcdbdbxaxdxxaaxcbxadbdabcbxaxcbxdaxaxxadxdxaxaxaxaxaxbdxbaccxxaxxxabaacxcxabdxaxxdxccaaxaaxbaxabaxbxaxdxxxaaxxccxaabdaaxxxaxxxxaaaaxcxxxaaxacdadaabbdabcddabdbaabaacdbaaadbbdxxbxacxxbaxxdbbxxdbbxxaxxacxxdaxbxbxbaxdabacbcadaaabbbcbacaadacdbaxdxdbxdbdaxbbxdaaxxaaxxxxdxcxaxdxaaacdbdbaacaadabbacbaxxdxacxbabxdaxdxaaccxabdbxxcxabadbaaabdadbadbdaaaacbxbdbabddbbacdacaccdaabbcdaaxaaacxadbxxxxcabaxxddxaxaxxdxbxxdbdxdbdaaaaabcababbcabdaacbcdbaaacbaaaacccxxaxcxaxabxaabxcdacdbdxdbxccxcaacxxxaxcbaxxxaaaxaddaaxcbdaxxxabbabxcxbdxxabaadadbaadaabbadbcdbaaadaaddbabbaaabdbadbadaxabbaxaxaaaxaaaxdadxcdacdabdabadabbdbaacdacdabacdbaxxxbxdacaxbbbxxxcxbbxxaxxaxxaaaaabaxadbddaadaxadxxxacxacxaxadabaxaxaadbaacxxxxxxdbdabacbaacaadbbaaabdabdxxbxbxxxaabxdxadxdxxbdxcxaaxbxxxaaxxbdaacbaddabcbbdbaabbdddacdadxaaxxacbaaxcdxxaxdxxbaxbdaxxxaaxbxaacacxxaxbxcbxbabdbdbcddabdabdbdaaabbddbacdabxaxxxxdxaacxxxcxaxaxbabxcbxaadxxxxxaacbxdbbdacdadxdxaxcaxaacbdbxddxadxxxbabxbxcbxxxxaxxbxbadxacadxadbdaabadbabdabbbadbdbcbxaxxaxaxaxbabxxbdabdabadacdbababdbcbdaccbbbaacadacbaacdaaabacbadabdabdbaabaaabcbabbdabdadababdxcxbdxaxxxcxxbdaaadbdbabbbbdbcbbaadbdxabxxdddxaxxbdxxbaaaxabxxbxaacddbbdbcbbdbdabdbcbcxaaxxxxcdxcaaxxdxdxaadxbacxbxxcxaxxadxbaxxxbbdaadacbddbdadacbcaaaddbdbacacbdbdabdbdbdbdbdabaaaddaadbcdbaaadadabdaaabbcdaaaxxbxcxaxxadabaxbdbxxacxbxabdaaabbbcaaabbabdbdacbcaccdabcdbadbdaaddbadadbdbaaaaxaadbbbbxbxdaxxaxbaaabxbxxxdxxbaaxxbdbbaddbdabdbdadbabacbadadbdxdbxadxcabaaxdacbaccdxxaxdxaxacbxxxxdxxbxxbxbxxdadxxxaabaaddaabaxxxaccbdxcdxxdaadxxaxadbdbdaaabdbdbadadbdbaacdaaadxdbaccbxdaxacxxdaxxxdaxacxadxdxbaaadbxxxxdxxcdadbacadacdabdacdbbdacacdadxaxxxbxdaxbdxadaacbbdabbdbabacbaaacdxcaxxcbxdacbaaxaaabxdaxxxxddxxaxxdaxdxaxxcbxaxxbxaaxxbdaxxxxdxxaxxcxcxxxdaabaaxxcxaaabacdaacbxbxbaxxxaxxdxxxxbadxxdabxacxaxxxxxaxxacbbxabxxaaacdxxaxxbadaaabbabdbbaaaacaacbbcdxacacxdbabdbxxbxddxaxxxdxbxxaaaaddxbaaxdaxadxaxxxdddxxxbbadadacbbaxxxxdxadabxabxxxxacxxacxxxxdaxdaccadxdaxbdbaxxbxdbdadababbadacaaacbbbddaaaabdaadbbdbdbadbdbdaacbaaxxxxbxaxxxxxaacdbxaxxxbaacxbadaaxxaxbdxcabcbbxxxbdabaabdabdbxxacdaccxaxaacaabdaadadadbacaaxdbxxaxbaabaacacaxbacxbxbxxbaxbxxxxbcbxbdbxcabdbxxcxxacxddbxxxxdxdxxadaxxaxacdxacdbaxcddadxxbbaxxbxxxcxbdxaaxdxxbddbbadadbbcdacdddaaaaacdbdbxbdxbxxabadaadadbxbabxxxaxbacxaacadbbaadxdaxcxxdxaxxbbxxcxxbxbcdxxbdbddbccaaadbbaadbdbdaddabbddbbaadbabacbdxxaxbaaxadxabaxaadbcbxxabdxxxxaccdxdxxaxdadaadxadxxdaxdxxxbxbxbbaxxdacdaaabadaaabdaacddaabaacdbbdbbabdacaadxbdxxxxxxaccaacdaaxxxxaaxxbbdbdxxacxdddbabdbaabaacabbdadaababaxxxbdbdbbaxdxbxbxacddxababbxbxcdbadaxabaxbaxaddbadbaabbcdbdaaddbbbdbccdbbdacaacbacadbbbbdaadbbbbcadbaaaacadbcbxadbdxcxcbxaxccxaxbxddbdbddbabaaadaacabadacdxdaxdadbaacdaxdxaxcbxaxbabacxaxdaxxxabxaaaxxdxxbacadbbdaaadacaacbacdacbxaxaxaaabxbxdaxxacxacdbxxaxxxccdabxxxxxxabdxbdadaxaxxxaxxaabxxbdadaababxxbxxxxaxxaaadbdxadbdxaaxdaadbxdbdbaacxxxabbxaacxxxxxxaxbxcbbxaaxxcaacxbaxacaaabxaxcbaxbddxdaxbacdxadbxbaddbbaaxacxabdxxbxbdxaxxaxbbaxcaxxdxdxxdbxbxxxxxxaacxacxaxcccdbbxdbdxcacaccdadacbacddbadbaacabcdabcadbabdddabdbbbabbcadadaaccbdbxxxaxxxaxacbxxacbcxaxdabaccabxaadbxaxbxabxbbxxddxxdxxxbaabdaaaaaaccaaaabcccaadaxaxxxxxadxxxbabaaacdabcdbbdadbaabacacacaadxababbdabxxxxcabxxxxxxxcbdaaccbbxbaddbcbbxdxacbxaaacxadxdbdxaxcxaacxxxxxxxbdaaxxxxxcxbbdaaxbdxaxaxxcaxcaadxcbadaaxxddbaxbbxaaxaxacadbbdbbcdbbdadaabbcbdbabaxbacbdaxaxxbdaxaxcaxaxaxccxdxadxdaxdaaxacxxcbxxbxxcaaaxxaxacbaxaxxbbaaaadadaxaxxaadaxaacxaaaxxbcxaacbcdadadaddbcbadbaacbddaadbdxcbabxbbxbxadadbcxxacxdabacdbxdacbxcbbaaabxxxaxadbdxbxxxxxxaxdaxabaaxcbddabcacdxxaxaadbaxaacbdbcaccaaaaadabdabbaaacdbcxabdbacbaxbxxaxxaxxaaxxdxxxxbbdadaadxaaxxcxaaxxdbabaaacdxxbabxaxbacxbddbcdaacdbdababcdacdacaddaaxbbdaadabdbadbbbacadacabdbdabdacbbadbdabdacacdbacdbdadxxxbcaxbcbdaaaxadxxxbbxbcxadaaxdabadxbadacxdaxacabxxxxbaxadxxxaaxdxaaxdbaxaxxxccbxbaxxxdaxdxcxxaxbxxxdbxxaaxbbbxdbxxxaxxxxadaxxdabxxxdxxdxbxdxxaxxxbxxbdbxaabbabdbaacadbdbacaacadbdaaacxdxcxxbacaaaaaabaaadbaddaabacbababaddabcbdbdbcbdbdbaadxdxaabaaxbxxbadxaaxdaxbxbxxxaaxxbxxbxbxdxabbdxbacbdbcabaaacadaadbcbxbaxcbabcdbccabbacbaaaaadaaaacbccxbdacaccaccbacabcadabbxdaxaxxxxaabxaxbabaxbxxbdxdxxxbxxxxacxaaaaddxacxbxacbcadaccbbdbabadbabaacbadbaaccbdbcdabxcxaxxxxaddadbaaxbbaxxxbaabdaaabdadabcdbacbadadxaccddaaadbcbadbabdbdbbdxaaabaxxxaaxbdaaxaxxabbaaxaxxxcbxxaxdxxxxdxcxbcbbdxdadxaaxdbacaacxcdbxcaaxxbxxaaxbxxxxxxxxbxcdxxxxdxaxaadbdbaaadaadadaddabbdbbaabxaabdxdxxbxxxcxaaxbbxxxbdbadxxxaxdbdbxaabbacxbaxxadacxxdaxxaxbdacxxxxxaaxdacbxdaaxbdbxdaxabxbdbdxabaadxxcxcbxadxxxabcxxcxcdxdbbbxdxxaaxaxxxxaxbbacbxdaacxxdaxxabaabaxaadbxaaxxcxbdxxbbaddbxaxxbabaaaxxxxdxxxxdbbxbxxdaxxxxcacddxaxxaxacdabbbabdbadbcddbabbdbdbabbxaadbdxaxbaadxdxxcdaaadbaadbacaacdbacaaaabababbbxxdxxbcbxcabxxdaxbxdaxdadxxxxxddxcxbxbdxdxxxadxxddaaaaabaacdbddaabddadaacacbaabdxxxaaadbdabaaaaaccabdbadbbbdacbaabadbaabdxaxxacxabxxdbacabaxbdaxdbxxdxbabadadbaadabdaadabcdaaacbadbcadbxdbcdbdxxbxbxxxdxxacxxcxdxdaxadbaabdbxacdbbaabxbxdaxadbxabdaxaadxxxcaxadxxbbaxbxdaxxxdbaxxdxabxaccaadacdbbbaacaddbadacbadacadaacbaaacaacbcbabdacadxxxxabxxxabbacdadadbaabdaaaaaaxaxcaaxcadbxxbaaacbcbabaabacdbbxxdaxxddxbxbdabaxaaaxxxabacdxaaabbxcdabdaxdaxbxxxcxaxbxbdxxbadxxdadabababaacdaabaabacdbddaaxxxaaxxxabxaxdadaxbcdaxxaxxdaaxxaxcxxcdxxxaaxxxaxacxaxxbbadbdacbxxaaadacxbaxxadxxdacbxaxacxabxxbcxaaadxdaxaxxxcaxaaxxxxxbabxdxaxxbaddbdaacdaabdabdbbcdbbdaddabdaaadxabaxccxaxbxadxxaxaabxdxaaadxaaxbaxabxxbxaxdacxxacaccabdbacdabbdbdaxaxacbdxxxbxxaxaxxdaaabddaxxbbxaxxxaxxdbabaxaaxabcdbxdaxaxdbxaadbbcbadaaabdabaaaccacxcdxxdbxxaxxaaxbbaaxbxxaxdxxbadaxbbxbbxaaabxabbxdxbdbdaaxxxxaxdxxabbcbdxcbxadxxaaxxaxbaxcaaxdxdaxdxxadbxadxxxdadaabxcbdxdbbcxbdaaxdacabaxabddbaadxaaxaxxxxdadbddbababcabaaacacdaaadbaabaaadaacdxxaabdxxbxxbbxxxbdxdadbbacabacbbxxdbxaxxxaxxxxdxbxxxcxaccxxxxbxxxxdbxbabxaxxxxxxxxdaxacxacaxbdbaaxxdbbddbxdbaacbadaaadbbacadaddacdacdbdabxaaxadxxbaadxcdbxxabdxbdbabdaacbdbbdbaacaababaaadadaadabadxaxaxxaaaaxdxaxbdxxxabxxxaxbbxdxxaxabaacbxxxbcxxbcaaabadaacdbdadabdbaabddbxbbcdxaaxxdaaaccbdabbdabbadbdadbdaaadaaaadbabaaaabadbbdbbaadbcdabaaaxxxxcdadxdacbacxbxxaaxxxaaxbdaxxaxbxxxxxxdxaxxdbacdbaaaxaaabbadxxcxaaxacbxxcxaxbaaaxcabxxdxxxbdxxaxxxbddaxaabcbxxbxbxaxdacacdaxxbddxadxaxxxxacbxxxbadxdbxxxxbdxxbxdxxdbxbdacxxbxbdxcbaaxdaxaxxxxbdddadaxxxaaabdbaxxxbadbxxaxcxxaaaxadabdxxdbxxxbxcaccbddxacdaaaxxbxbxxcbxaxxxxxxxdxcadaaxbacbaaddaacaddaadbaadaabadbdbabaadabaabbcdaaacxadbxxbadxbabxxxxaxxaxdxxaaxaacbxaaxbaadbxxdxdadaxdaaxaddaxxxxxxdbcbxxbxcbaaacaaacaaaacbdaacadaabdaaacdabbaabcadaaacbadacdabbadabcdaadxbdaacadaacdbdaadbcabaccadbaaaaxbbabaxaxaabaaxaadxaxabaxxdxxdxxxbcxxc diff --git a/middlesub/grpwk.c b/middlesub/grpwk.c index a316dbc..b4140c1 100644 --- a/middlesub/grpwk.c +++ b/middlesub/grpwk.c @@ -36,7 +36,8 @@ char *grpwk(char *t, string_s *s, int len) for (int i = 0; i < T_LENGTH; i++) linked_init(&t_opt[i]); linked_list s_count[len]; - memset(s_count, 0, sizeof(linked_list) * len);; + memset(s_count, 0, sizeof(linked_list) * len); + ; BM(t_in, s, bm_until, t_out, s_count, t_opt); printf("bm done\n"); @@ -54,7 +55,9 @@ char *grpwk(char *t, string_s *s, int len) // usleep(10000); // } t[i] = t_out->str[i]; - } else if (t[i] == 'x') t[i] = 'a'; + } + else if (t[i] == 'x') + t[i] = 'a'; } // return t; @@ -141,7 +144,8 @@ char *grpwk(char *t, string_s *s, int len) for (int i = 0; i < T_LENGTH; i++) { - if (t_out->str[i] != 'x') { + if (t_out->str[i] != 'x' && t_in->str[i] == 'x') + { t[i] = t_out->str[i]; } } diff --git "a/\346\217\220\345\207\272\347\224\250/4.tar" "b/\346\217\220\345\207\272\347\224\250/4.tar" new file mode 100644 index 0000000000000000000000000000000000000000..80ac14d984530e8ad7b3d0466fa72157ee609442 GIT binary patch literal 130560 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�V0B*Qw?&NH^e=l9fOm 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 F{uhQjrXc_T literal 0 HcmV?d00001 diff --git "a/\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" "b/\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" new file mode 100644 index 0000000000000000000000000000000000000000..be537eb44ca1e347e7a761c14b4f312c3e8c9543 GIT binary patch literal 27 fcma!!%Fjy;DN4*MPD?F{<>dl#JyUFrdAS$>i985_ literal 0 HcmV?d00001 diff --git "a/\346\217\220\345\207\272\347\224\250/ahocorasick.c" "b/\346\217\220\345\207\272\347\224\250/ahocorasick.c" new file mode 100644 index 0000000..e4cd6ee --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/ahocorasick.c" @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "ahocorasick.h" + +// ahocorasick型の変数の初期化 +void aho_init(ahocorasick * aho, string_s *s) { + memset(aho, 0, sizeof(ahocorasick)); + aho->s = s; +} + +void aho_destroy(ahocorasick * aho) { + aho_clear_trie(aho); +} + +/** キー(string_s *s_i)を木に追加 + * return 挿入成功:TRUE、容量を超過:FALSE + */ +int aho_add_match_text(ahocorasick * aho, string_s *text) { + trie_add(&aho->trie, text, text->str); + return TRUE; +} + +/** 曖昧検索用文字列挿入用(木に挿入する文字列と探索成功時の返す文字列が違う場合に使用) + * 木に挿入する文字列をメモリに保存せずに済む + * data:曖昧の文字列、original:虫食い前のデータ + */ +int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original) { + trie_add(&aho->trie, original, data); + return TRUE; +} + +// トライ木を生成 +void aho_create_trie(ahocorasick * aho) { + trie_init(&aho->trie); +} + +// トライ木からアホコラを作る +void aho_connect_trie(ahocorasick * aho) { + trie_connect(&aho->trie); +} + +void aho_clear_trie(ahocorasick * aho) { + trie_destroy(&aho->trie); +} + +/** 検索関数(data:t'、len:len(t')) + * return マッチしたキーの数 + */ +int aho_search(ahocorasick * aho, char *data, int len) { + int counter = 0; + aho_node *current = &aho->trie.root; + + for (int i=0; idata); + aho->callback_match(aho, result, i); + } + + return counter; +} + +// 探索が成功した際に実行される関数を設定する関数 +inline void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)) { + aho->callback_match = callback_match; +} + +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count) { + aho->t_opt = t_opt; + aho->s_count = s_count; +} diff --git "a/\346\217\220\345\207\272\347\224\250/ahocorasick.h" "b/\346\217\220\345\207\272\347\224\250/ahocorasick.h" new file mode 100644 index 0000000..690d6b3 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/ahocorasick.h" @@ -0,0 +1,31 @@ +#pragma once + +#include "ahotrie.h" +#include "string_info.h" +#include "linked_list.h" + +#define AHO_SIZE 45000 + +typedef struct _ahocorasick { + aho_trie trie; + string_s *s; + + void (*callback_match)(struct _ahocorasick * aho, linked_list* l, int pos); + linked_list *t_opt; + linked_list *s_count; +} ahocorasick; + +void aho_init(ahocorasick * aho, string_s *s); +void aho_destroy(ahocorasick * aho); + +int aho_add_match_text(ahocorasick * aho, string_s *text); +int aho_add_similar_text(ahocorasick * aho, char * data, string_s * original); + +void aho_create_trie(ahocorasick * aho); +void aho_connect_trie(ahocorasick * aho); +void aho_clear_trie(ahocorasick * aho); + +int aho_search(ahocorasick * aho, char *text, int len); + +void aho_register_match_callback(ahocorasick * aho, void (*callback_match)(ahocorasick * aho, linked_list* l, int pos)); +void aho_register_option_lists(ahocorasick * aho, linked_list *t_opt, linked_list *s_count); diff --git "a/\346\217\220\345\207\272\347\224\250/ahotrie.c" "b/\346\217\220\345\207\272\347\224\250/ahotrie.c" new file mode 100644 index 0000000..aef65f1 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/ahotrie.c" @@ -0,0 +1,160 @@ +#include +#include +#include + +#include "ahotrie.h" +#include "queue.h" + +// 新しいノードを生成 +aho_node *node_init(int data, aho_node * parent) { + aho_node *node = (aho_node *)malloc(sizeof(aho_node)); + memset(node, 0, sizeof(aho_node)); + node->data = data; + node->parent = parent; + node->ref_count = 1; + node->end = FALSE; + linked_init(&node->output_list); + return node; +} + +// トライ木を初期化 +void trie_init(aho_trie * t) { + if (t == NULL) t = (aho_trie *)malloc(sizeof(aho_trie)); + memset(t, 0, sizeof(aho_trie)); + t->root = *node_init(-1, NULL); +} + +// トライ木消去 +void trie_destroy(aho_trie * t) { + trie_delete(t); +} + +/** トライ木に文字列を挿入 + * string_s *text: ゴール + * char *similar: 入力文字列 + * - aho_add_match_textのときは text->str == similar + **/ +int trie_add(aho_trie * t, string_s * text, char * similar) { + aho_node *current = &t->root; + + for (int i=0; ilen; i++) { + int char_id = similar[i] - 'a'; + if (char_id > MAX_NODE - 1 || char_id < 0) return FALSE; + + if (current->child[char_id] == NULL) current->child[char_id] = node_init(char_id, current); + else current->child[char_id]->ref_count++; + + current = current->child[char_id]; + } + + current->end = TRUE; + linked_push_int(¤t->output_list, text->id, 1); + + return TRUE; +} + +int connect_link(aho_node *p, aho_node *q) { + if (p->failure_link == NULL || p->parent == NULL) { + q->failure_link = p; + return TRUE; + } + + aho_node *tmp = p->failure_link; + for (int i=0; ichild[i] == NULL) continue; + + if (tmp->child[i]->data == q->data) { + q->failure_link = tmp->child[i]; + + if (tmp->child[i]->end) q->output_link = tmp->child[i]; + else q->output_link = tmp->child[i]->output_link; + + return TRUE; + } + } + return FALSE; +} + +// トライ木をアホコラに合わせて再構成 +void trie_connect(aho_trie * t) { + queue que; + que_init(&que); + que_push(&que, &t->root); + + while (TRUE) { + aho_node *node = que_pop(&que); + if (node == NULL) break; + + for (int i=0; ichild[i] == NULL) continue; + + que_push(&que, node->child[i]); + + aho_node *tmp = node, *child = node->child[i]; + while (connect_link(tmp, child) == FALSE) tmp = tmp->failure_link; + } + } + + que_destroy(&que); +} + +void trie_delete(aho_trie * t) { + queue que; + que_init(&que); + que_push(&que, &t->root); + + while (TRUE) { + QUE_TYPE node = que_pop(&que); + if (node == NULL) break; + + for (int i=0; ichild[i] != NULL) que_push(&que, node->child[i]); + linked_destroy(&node->output_list); + + if (node->parent == NULL) continue; + free(node); + } + + que_destroy(&que); +} + +int find_node(aho_node ** node, int text) { + if (*node == NULL) return FALSE; + if (text > MAX_NODE - 1 || text < 0) return FALSE; + + if ((*node)->child[text] != NULL) { + *node = (*node)->child[text]; + return TRUE; + } + + return FALSE; +} + +// textが木に含まれる場合、終端に設定したlinked_listを返す。含まれない場合はNULL。 +linked_list *trie_find(aho_node ** node, char text) { + while (find_node(node, text - 'a') == FALSE) { + if (node == NULL || (*node)->parent == NULL) return NULL; + *node = (*node)->failure_link; + } + + if ((*node)->end) return &(*node)->output_list; + else if ((*node)->output_link) return &(*node)->output_link->output_list; + else return NULL; +} + +// トライ木を表示。ノードが多くなってくると使い物にならない。 +void trie_print(aho_trie * t) { + queue que; + que_init(&que); + que_push(&que, &t->root); + + while (TRUE) { + QUE_TYPE node = que_pop(&que); + if (node == NULL) break; + + for (int i=0; ichild[i] != NULL) que_push(&que, node->child[i]); + + printf("%c, refs:%d, fail: %p, output:%p\n", node->data + 'a', node->ref_count, node->failure_link, node->output_link); + } + + que_destroy(&que); +} diff --git "a/\346\217\220\345\207\272\347\224\250/ahotrie.h" "b/\346\217\220\345\207\272\347\224\250/ahotrie.h" new file mode 100644 index 0000000..b494ad5 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/ahotrie.h" @@ -0,0 +1,34 @@ +#pragma once + +#include "string_info.h" +#include "linked_list.h" + +#define MAX_NODE 4 +#define FALSE 0 +#define TRUE 1 + +typedef struct _node { + int data; + unsigned int ref_count; + + struct _node *parent, *child[MAX_NODE]; + + int end; + linked_list output_list; + + struct _node *failure_link, *output_link; +} aho_node; + +typedef struct { + aho_node root; +} aho_trie; + +void trie_init(aho_trie * t); +void trie_destroy(aho_trie * t); + +int trie_add(aho_trie * t, string_s * text, char * parent); +void trie_connect(aho_trie * t); +void trie_delete(aho_trie * t); +linked_list *trie_find(aho_node ** t, char text); + +void trie_print(aho_trie * t); diff --git "a/\346\217\220\345\207\272\347\224\250/constructions.c" "b/\346\217\220\345\207\272\347\224\250/constructions.c" new file mode 100644 index 0000000..fe08ab4 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/constructions.c" @@ -0,0 +1,109 @@ +// +// Created by world on 2019/12/07. +// +#include +#include +#include +#include "constructions.h" + +int comp(const void *p, const void *q) +{ + return ((string_s *)q)->len - ((string_s *)p)->len; +} + +void ConstructSMatrix(string_s * s_i,int matsize) +{ + printf("Accepted input text\n"); + qsort(s_i, matsize, sizeof(string_s), comp); + printf("s_i sort complete\n"); +} + +void ConstructTout(string_out *t_out, char *t_temp){ + strcpy(t_out->str, t_temp); + int i; + for(i=0; t_temp[i] != '\0'; i++){ + t_out->str[i] = 'x'; + } + //printf("Preparing output text structure\n"); +} + +void ConstructTin(string_out *t_in, char *t_temp){ + strcpy(t_in->str, t_temp); + int i,j,start=0,temp_id=-1; + if(t_temp[0] == 'x'){ + for(i=0;t_temp[i]=='x';i++) + start = i; + } + for(i=start; t_temp[i] != '\0'; i++){ + if(t_temp[i] == 'x'){ + temp_id = i-1; + for(j=1;t_temp[i - 1 + j]=='x'; j++){ + t_in->shift_var[i-1 + j] = j; + } + i+=j-1; + } + } + //printf("Preparing input text structure\n"); +} + +/* + + +Link NEW(Item item, Link f, Link b) +{ + Link x = malloc(sizeof *x); + x->item = item; + x->f = f; + x->b = b; + return x; +} + +void ConstructDLL(char s[120], int n) +{ + Item temp; + key(temp) = n; + strcpy(temp.Str, s); + + if (head == NULL) + { + head = NEW(temp, NULL, tail, 0); + tail = head; + } + else + { + tail->b = NEW(temp, tail, NULL, 0); + tail = tail->b; + } +} + +void Assign(string_s *S_temp, Link link_temp, int n) +{ + if (link_temp == tail) + { + strcpy(S_temp[n].str, (link_temp->item).Str); + S_temp[n].len = strlen((link_temp->item).Str); + } + else + { + Assign(S_temp, link_temp->b, n + 1); + strcpy(S_temp[n].str, (link_temp->item).Str); + S_temp[n].len = strlen((link_temp->item).Str); + } +} + +int comp(const void *p, const void *q) +{ + //printf("compared\n"); + return ((string_s *)q)->len - ((string_s *)p)->len; +} + +void ConstructSMatrix(int n) +{ + string_s *S_temp; + S_temp = malloc(sizeof(string_s *) * n); + S = S_temp; + Assign(S, head, 0); + qsort(S, n, sizeof(string_s), comp); + printf("sort complete\n"); +} + */ \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/constructions.h" "b/\346\217\220\345\207\272\347\224\250/constructions.h" new file mode 100644 index 0000000..59ad708 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/constructions.h" @@ -0,0 +1,7 @@ +// +// Created by world on 2019/12/07. +// +#include "string_info.h" +void ConstructSMatrix(string_s * s_i, int matsize); +void ConstructTout(string_out *t_out, char *t_in); +void ConstructTin(string_out *t_in, char *t_temp); diff --git "a/\346\217\220\345\207\272\347\224\250/input_win.c" "b/\346\217\220\345\207\272\347\224\250/input_win.c" new file mode 100644 index 0000000..ce775a2 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/input_win.c" @@ -0,0 +1,68 @@ +#include +#include +#include +#include +// #include +// #include +#include +#include "string_info.h" + +// TODO: change here to include your files!! +#include "itoi/grpwk.h" + +int main_prg(int, char **); + +int main(int argc, char **argv) +{ + // struct rusage u; + // getrusage(RUSAGE_SELF, &u); + // struct timeval start = u.ru_utime; + + clock_t c_start = clock(), c_end; + main_prg(argc, argv); + + // struct timeval end = u.ru_utime; + c_end = clock(); + + printf("%f\n", (double)(c_end - c_start) / CLOCKS_PER_SEC); + // fprintf(stderr, "%lf\n", (double)(end.tv_sec - start.tv_sec) + (double)(end.tv_usec - start.tv_usec) * 1e-6); + return 0; +} + + +int sort_f(const void *a, const void *b) { + return ((string_s *)b)->len - ((string_s *)a)->len; +} + +int main_prg(int argc, char **argv) +{ + + assert(argc == 3); + FILE *fp_in = fopen(argv[1], "r"); + assert(fp_in != NULL); + FILE *fp_out = fopen(argv[2], "w"); + assert(fp_out != NULL); + + + + char t[T_LENGTH]; + string_s s[50000]; + //s = malloc(sizeof(string_s) * 50000); + + // input t + fscanf(fp_in, "%s", t); + // for (int i=0; i +#include +#include + +#include "linked_list.h" + +linked_node *linked_node_init(int data) { + linked_node *tmp = (linked_node *)malloc(sizeof(linked_node)); + tmp->data = data; + tmp->place = 0; + tmp->next = NULL; + tmp->prev = NULL; + return tmp; +} + +void linked_init(linked_list *l) { + l->length = 0; +} + +void linked_destroy(linked_list *l) { + while (l->length != 0) free(linked_pop_node(l, 0)); +} + +int linked_search_int(linked_list *l, int data) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data) return 1; + } + return 0; +} + +int linked_search_node(linked_list *l, int data, int place) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data && iter->place == place) return 1; + } + return 0; +} + +// insert data to bottom of list +int linked_push_int(linked_list *l, int data, int search) { + if (search && linked_search_int(l, data)) return 0; + linked_node *tmp = linked_node_init(data); + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->bottom->next = tmp; + tmp->prev = l->bottom; + l->bottom = tmp; + } + return 1; +} + +// insert data to top of list +int linked_unshift_int(linked_list *l, int data, int search) { + if (search && linked_search_int(l, data)) return 0; + linked_node *tmp = linked_node_init(data); + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->top->prev = tmp; + tmp->next = l->top; + l->top = tmp; + } + return 1; +} + +// look at data of index (negative value for looking from the bottom: -1:=l->bottom->data) +int linked_seek_int(linked_list *l, int index) { + if (index == 0) return l->top->data; + else if (index == -1) return l->bottom->data; + else if (index > 0) { + linked_node *iter = l->top->next; + for (int i=1; inext; + return iter->data; + } else if (index < 0) { + linked_node *iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + return iter->data; + } + return 0; +} + +// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) +int linked_pop_int(linked_list *l, int index) { + linked_node *iter = NULL; + if (index == 0) { + iter = l->top; + l->top = iter->next; + } else if (index == -1) { + iter = l->bottom; + l->bottom = iter->prev; + } else { + if (index > 0) { + iter = l->top->next; + for (int i=1; inext; + } else { + iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + } + if (iter->prev != NULL) iter->prev->next = iter->next; + if (iter->next != NULL) iter->next->prev = iter->prev; + } + if (iter != NULL) { + l->length--; + if (l->length == 0) { + l->top = NULL; + l->bottom = NULL; + } + int data = iter->data; + free(iter); + return data; + } else return 0; +} + +// insert data and place to bottom of list +int linked_push_node(linked_list *l, int data, int place, int search) { + if (search && linked_search_node(l, data, place)) return 0; + linked_node *tmp = linked_node_init(data); + tmp->place = place; + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->bottom->next = tmp; + tmp->prev = l->bottom; + l->bottom = tmp; + } + return 1; +} + +// insert data and place to top of list +int linked_unshift_node(linked_list *l, int data, int place, int search) { + if (search && linked_search_node(l, data, place)) return 0; + linked_node *tmp = linked_node_init(data); + tmp->place = place; + if (l->length++ == 0) { + l->top = tmp; + l->bottom = tmp; + } else { + l->top->prev = tmp; + tmp->next = l->top; + l->top = tmp; + } + return 1; +} + +// return node of index (negative value for looking from the bottom: -1:=l->bottom) +linked_node *linked_seek_node(linked_list *l, int index) { + if (index == 0) return l->top; + else if (index == -1) return l->bottom; + else if (index > 0) { + linked_node *iter = l->top->next; + for (int i=1; inext; + return iter; + } else if (index < 0) { + linked_node *iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + return iter; + } + return NULL; +} + +// delete the data of index and return (negative value for counting from the bottom: -1=l->bottom->data) +linked_node *linked_pop_node(linked_list *l, int index) { + linked_node *iter = NULL; + if (index == 0) { + iter = l->top; + l->top = iter->next; + } else if (index == -1) { + iter = l->bottom; + l->bottom = iter->prev; + } else { + if (index > 0) { + iter = l->top->next; + for (int i=1; inext; + } else { + iter = l->bottom->prev; + for (int i=-2; i>index; i--) iter = iter->prev; + } + iter->prev->next = iter->next; + iter->next->prev = iter->prev; + } + if (iter != NULL) { + l->length--; + return iter; + } else return NULL; +} + +void linked_print(linked_list *l) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter = iter->next) { + printf("(%d, %d) ", iter->data, iter->place); + } + printf("\n"); +} + +int linked_delete_int(linked_list *l, int data) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter=iter->next) { + if (iter->data == data) { + linked_pop_int(l, v); + return 1; + } + } + return 0; +} \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/linked_list.h" "b/\346\217\220\345\207\272\347\224\250/linked_list.h" new file mode 100644 index 0000000..4627624 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/linked_list.h" @@ -0,0 +1,28 @@ +#pragma once + +typedef struct _linked_node { + int data, place; + struct _linked_node *next, *prev; +} linked_node; + +typedef struct { + linked_node *top, *bottom; + int length; +} linked_list; + +void linked_init(linked_list *l); +void linked_destroy(linked_list *l); + +int linked_push_int(linked_list *l, int data, int search); +int linked_unshift_int(linked_list *l, int data, int search); +int linked_seek_int(linked_list *l, int index); +int linked_pop_int(linked_list *l, int index); + +int linked_push_node(linked_list *l, int data, int place, int search); +int linked_unshift_node(linked_list *l, int data, int place, int search); +linked_node *linked_seek_node(linked_list *l, int index); +linked_node *linked_pop_node(linked_list *l, int index); + +int linked_delete_int(linked_list *l, int data); + +void linked_print(linked_list *l); \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" new file mode 100644 index 0000000..84431dc --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" @@ -0,0 +1,180 @@ +// +// Created by world on 2019/12/07. +// +#pragma GCC optimize("O3") + +#include +#include +#include "../constructions.h" +#include "BM.h" + +void BM(string_out *t_in, string_s *s, int to, string_out *t_out, linked_list *s_count, linked_list *t_opt) +{ + /*----------------------initialize-------------------------*/ + int t_id, esc, comp_var, point, t_len = strlen(t_in->str); + string_s *s_i; + + /*---------------------------------------------------------*/ + for (int i = 0; i < to; i++) + { + s_i = &s[i]; + //t_id:s_iの最後尾がいる場所 + t_id = s_i->len - 1; + //esc:一致した文字の個数 + esc = 0; + //comp_var:何回比較したか + comp_var = 0; + //point:比較済みの文字の中で左から見てxに最も近い場所 + point = t_id; + int table[110][4]; + + /*---------------------makeShiftTable----------------------*/ + for (int k = 0; k < s_i->len- 1; k++) + { + int Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (0 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][0] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (1 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][1] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (2 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][2] = Tcounter; + rep(j, 120) + { + Tcounter = j; + if ((s_i->str[s_i->len - 1 - k - j] == (3 + 'a')) || (s_i->len - 1 - k - j < 0)) + break; + } + table[k][3] = Tcounter; + } + /*---------------------------------------------------------*/ + + while (t_id - 1 <= t_len) + { + int flag = 1; + //s_xが検出済で既に挿入されている場合、挿入済箇所をスキップ + if (t_out->str[t_id] != 'x') + { + t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); + point = t_id; + } + + //s_iが指定位置t_idにマッチするか確認 + int branch = (t_in->str[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); + if (((t_in->str[t_id - comp_var] != 'x') && branch)) + { + //failware + flag = 0; + esc = 0; + } + else if (!branch) + { + //success + esc++; + comp_var++; + } + else + { + //ignore + comp_var += t_in->shift_var[t_id - comp_var]; + point = t_id - comp_var; + } + + while ((flag == 1) && (esc < 23) && (s_i->len - 1 - comp_var >= 0) && (t_id - comp_var != 0)) + { + if (t_out->str[t_id] != 'x') + { + t_id += High(t_out->shift_var[t_id - s_i->len], t_out->shift_var[t_id]); + point = t_id; + } + /*----------------------DebugPrint-------------------------*/ +/* + printf("t_s:"); + int j; + for(j=0;jstr);j++) + printf("%d",t_out->shift_var[j]); + printf("\nt :%s\n",t_in->str); + printf("out:%s\n",t_out->str); + printf("s_i:"); + + for(j=0;jlen+1;j++) + printf(" "); + printf("%s\n",s_i->str); + printf("cmp:"); + for(j=0;jstr[t_id - comp_var] != s_i->str[s_i->len - 1 - comp_var]); + if (((t_in->str[t_id - comp_var] != 'x') && branch)) + { + //failware + flag = 0; + esc = 0; + } + else if (!branch) + { + //success + esc++; + comp_var++; + } + else + { + //ignore + comp_var += t_in->shift_var[t_id - comp_var]; + } + } + //マッチした場合t_outに挿入,そうでないなら次の場所を探索 + if (flag == 1) + { + if (s_i->len > 22) + { + int x, y; + for (x = s_i->len - 1, y = 0; x >= 0; x--, y++) + { + t_out->str[t_id - y] = s_i->str[x]; + t_out->shift_var[t_id - y] = s_i->len - x - 1; + } + t_out->shift_var[t_id - y] = s_i->len; + esc = 0; + goto next; + } + else + { + linked_push_int(&s_count[s_i->id], t_id - s_i->len + 1, 0); + for (int j = 0; j < s_i->len; j++) + { + linked_push_node(&t_opt[t_id - s_i->len+ 1 + j], s_i->id, j, 0); + } + } + } + int temp = High(table[t_id - point + 1][t_in->str[point] - 'a'] + 1, + table[comp_var][t_in->str[t_id - comp_var] - 'a']); + + t_id += temp; + comp_var = 0; + point = t_id; + } + next:; + } +} diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" new file mode 100644 index 0000000..3e7a00f --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/BM.h" @@ -0,0 +1,17 @@ +#pragma once + +#include "../string_info.h" +#include "../linked_list.h" + +typedef struct Node *Link; +struct Node{ + int *id; + Link b; + int *x; + int *count; +}; + +#define High(A, B) (A > B) ? A : B +#define rep(i, n) for (int i = 0; i < (int)(n); i++) + +void BM(string_out * t_in, string_s * s, int to, string_out *t_out, linked_list *s_count, linked_list *s_opt); diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" new file mode 100644 index 0000000..b4140c1 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" @@ -0,0 +1,156 @@ +#include +#include +#include + +#include "../constructions.h" +#include "grpwk.h" +#include "itoi.h" +#include "BM.h" +#include + +// input_win.cから呼び出されるやつ +char *grpwk(char *t, string_s *s, int len) +{ + /* 文字数の区切りを決定 */ + int bm_until, aho_until; + for (bm_until = 0; bm_until < len; ++bm_until) + if (s[bm_until].len <= BM_TO) + break; + for (aho_until = bm_until; aho_until < len; aho_until++) + if (s[aho_until].len <= AHO_TO) + break; + + /* BMはじめ */ + string_out *t_in = (string_out *)malloc(sizeof(string_out)); + string_out *t_out = (string_out *)malloc(sizeof(string_out)); + + for (int i = 0; i < T_LENGTH; i++) + { + t_out->str[i] = 'x'; + } + t_out->str[T_LENGTH] = '\0'; + ConstructTin(t_in, t); + + // init option lists + linked_list *t_opt = (linked_list *)malloc(sizeof(linked_list) * T_LENGTH); + for (int i = 0; i < T_LENGTH; i++) + linked_init(&t_opt[i]); + linked_list s_count[len]; + memset(s_count, 0, sizeof(linked_list) * len); + ; + BM(t_in, s, bm_until, t_out, s_count, t_opt); + printf("bm done\n"); + + // int err = 0; + // for (int i = 0; i < T_LENGTH; i++) + // err += (t_in->str[i] != t_out->str[i] && t_in->str[i] != 'x' && t_out->str[i] != 'x' ); + // printf("err:%d\n",err); + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x') + { + // if (t[i] != t_out->str[i]) + // { + // printf("error: %d\n", i); + // usleep(10000); + // } + t[i] = t_out->str[i]; + } + else if (t[i] == 'x') + t[i] = 'a'; + } + // return t; + + ahocoralike(t, s, bm_until, aho_until, t_opt, s_count); + printf("ahocora done\n"); + + linked_list s_opt[100]; + memset(s_opt, 0, sizeof(linked_list) * 100); + // s_opt init + for (int i = 0; i < aho_until; i++) + { + s_opt_insert(s_opt, s_count[i].length, i); + } + + /* delete options where t is already determined by BM */ + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x') + { + discriminate(i, t_opt, s_opt, s_count); + } + } + printf("discrim done\n"); + + /* TODO: test */ + // for (int i=0; ilen; i++) + { + discriminate(s_pos + i, t_opt, s_opt, s_count); + } + + /* insert text to ans */ + for (int i = 0; i < text->len; i++) + { + // if (t_out->str[s_pos + i] != 'x') printf("eorro\n"); + t_out->str[s_pos + i] = text->str[i]; + } + } + + for (int i = 0; i < 100; i++) + linked_destroy(&s_opt[i]); + for (int i = 0; i < T_LENGTH; i++) + linked_destroy(&t_opt[i]); + free(t_opt); + + for (int i = 0; i < T_LENGTH; i++) + { + if (t_out->str[i] != 'x' && t_in->str[i] == 'x') + { + t[i] = t_out->str[i]; + } + } + + free(t_in); + free(t_out); + return t; +} diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" new file mode 100644 index 0000000..d8f02f2 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" @@ -0,0 +1,9 @@ +#pragma once + +#include "../string_info.h" +#include "../linked_list.h" + +#define BM_TO 16 +#define AHO_TO 11 + +char *grpwk(char *t, string_s *s, int len); diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" new file mode 100644 index 0000000..79e4da8 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" @@ -0,0 +1,98 @@ +#include +#include +#include + +#include "../ahocorasick.h" +#include "itoi.h" + +// outcome functions for testing +void callback_add2linked_list(ahocorasick * aho, linked_list *l, int pos) { + linked_node *iter = l->top; + for (int v=0; vlength; v++, iter = iter->next) { + string_s *text = &aho->s[iter->data]; + + // s_count[i].append(text.pos) + linked_push_int(&aho->s_count[iter->data], pos-text->len+1, 1); // <- index of first letter + + // t_opt[i].append(i, place) + for (int i=0; ilen; i++) { + linked_push_node(&aho->t_opt[pos-text->len+1 + i], iter->data, i, 1); + } + } +} + +// 入力されたintの中で何個のビットが立っているかを返す +int bitcount(unsigned long long bits) { + bits = (bits & 0x5555555555555555) + (bits >> 1 & 0x5555555555555555); + bits = (bits & 0x3333333333333333) + (bits >> 2 & 0x3333333333333333); + bits = (bits & 0x0f0f0f0f0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f0f0f0f0f); + bits = (bits & 0x00ff00ff00ff00ff) + (bits >> 8 & 0x00ff00ff00ff00ff); + bits = (bits & 0x0000ffff0000ffff) + (bits >> 16 & 0x0000ffff0000ffff); + return (bits & 0x00000000ffffffff) + (bits >> 32 & 0x00000000ffffffff); +} + +// bitchangeにおいて立っているビットの場所の文字を'a'に置換する +void convert(char *tmp, char *s, int len, unsigned long long bitchange) { + for (int i=0; i> i & 1) tmp[i] = 'a'; + else tmp[i] = s[i]; + } + tmp[len] = '\0'; +} + +// アホコラを使用したあいまい検索の関数 +void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count) { + /* おまじない */ + ahocorasick aho; + aho_init(&aho, s); + aho_create_trie(&aho); + aho_register_option_lists(&aho, t_opt, s_count); + aho_register_match_callback(&aho, callback_add2linked_list); + + char tmp[120]; + + for (int i=from; idata].length == 0) { // same as the insert option + free(other); + continue; + } + + // go to s_count[other.id] and delete the option to insert here + if (linked_delete_int(&s_count[other->data], t_index - other->place)) { + // reinsert the deleted option to s_opt + s_opt_insert(s_opt, s_count[other->data].length, other->data); + } + free(other); + } +} \ No newline at end of file diff --git "a/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" new file mode 100644 index 0000000..7c9962f --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" @@ -0,0 +1,9 @@ +#pragma once + +#include "../string_info.h" +#include "../linked_list.h" + +void ahocoralike(char *t, string_s s[], int from, int to, linked_list *t_opt, linked_list *s_count); + +int s_opt_insert(linked_list *s_opt, int s_count, int index); +void discriminate(int t_index, linked_list *t_opt, linked_list *s_opt, linked_list *s_count); diff --git "a/\346\217\220\345\207\272\347\224\250/queue.c" "b/\346\217\220\345\207\272\347\224\250/queue.c" new file mode 100644 index 0000000..b746f52 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/queue.c" @@ -0,0 +1,52 @@ +#include +#include +#include "queue.h" +#include + +void que_init(queue *que) +{ + que->data = (QUE_TYPE *)malloc(sizeof(QUE_TYPE) * MAX_SIZE); + que->front = 0; + que->back = 0; + que->size = 0; +} + +void que_push(queue *que, QUE_TYPE value) +{ + if (que->size >= MAX_SIZE) + { + printf("キューの容量がいっぱいです\n"); + return; + } + que->data[que->back] = value; + que->back = (que->back + 1) % MAX_SIZE; + que->size++; +} + +QUE_TYPE que_pop(queue *que) +{ + if (que->size == 0) + { + // printf("キューの中身は空です\n"); + return NULL; + } + QUE_TYPE top = que->data[que->front]; + que->front = (que->front + 1) % MAX_SIZE; + que->size--; + return top; +} + +void que_destroy(queue *que) { + free(que->data); +} + +// void printQue(queue *que) +// { +// int i; +// printf("data : "); +// for (i = que->front; i < que->back; i++) +// { +// printf("%p ", que->data[i]); +// } +// printf("\n"); +// } diff --git "a/\346\217\220\345\207\272\347\224\250/queue.h" "b/\346\217\220\345\207\272\347\224\250/queue.h" new file mode 100644 index 0000000..cd892a7 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/queue.h" @@ -0,0 +1,25 @@ +#pragma once + +#include "ahotrie.h" + +#ifndef QUEUE_H +#define QUEUE_H + +#define QUE_TYPE aho_node* +#define MAX_SIZE 8000000 + +typedef struct +{ + QUE_TYPE *data; + int front; + int back; + int size; +} queue; + +void que_init(queue *); +void que_push(queue *, QUE_TYPE); +QUE_TYPE que_pop(queue *); +void que_destroy(queue *); +// void printQue(queue *); + +#endif diff --git "a/\346\217\220\345\207\272\347\224\250/string_info.h" "b/\346\217\220\345\207\272\347\224\250/string_info.h" new file mode 100644 index 0000000..ba95f16 --- /dev/null +++ "b/\346\217\220\345\207\272\347\224\250/string_info.h" @@ -0,0 +1,13 @@ +#pragma once + +typedef struct { + char str[120]; + int len, id; +} string_s; + +#define T_LENGTH 400001 + +typedef struct { + char str[T_LENGTH + 1]; + int shift_var[T_LENGTH]; +} string_out; From c78a1e3320ffd175957fe127bf63da8b7bb6cc4e Mon Sep 17 00:00:00 2001 From: udemegane Date: Sun, 22 Dec 2019 23:34:42 +0900 Subject: [PATCH 36/37] Update 4.tar --- "\346\217\220\345\207\272\347\224\250/4.tar" | Bin 130560 -> 52736 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git "a/\346\217\220\345\207\272\347\224\250/4.tar" "b/\346\217\220\345\207\272\347\224\250/4.tar" index 80ac14d984530e8ad7b3d0466fa72157ee609442..268ff42a04f3a8f76e3f370a36b49c0cf4b96c09 100644 GIT binary patch delta 37 tcmZqp!`?85d4bKg9L5QHyynJ63 literal 130560 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�V0B*Qw?&NH^e=l9fOm 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 F{uhQjrXc_T From f8f17d94ecd3d8ff213babfdc164c46111265e6c Mon Sep 17 00:00:00 2001 From: pysan3 Date: Fri, 27 Dec 2019 18:35:23 +0900 Subject: [PATCH 37/37] middle submission --- .gitignore | 21 +- BC_readme.txt | 252 ----------------- CMakeLists.txt | 6 - a.out | Bin 12696 -> 0 bytes analyze.py | 120 -------- compile.sh | 2 +- example/BM+.c | 256 ------------------ example/BM.h | 36 --- example/grpwk.c | 30 -- example/grpwk.h | 5 - input_win.c | 2 +- itoi/grpwk.c | 75 ----- itoi/grpwk.h | 9 - itoi/itoi.c | 98 ------- itoi/itoi.h | 9 - out.txt | 0 test_main.c | 6 - queue_test.c => test_queue.c | 0 .../Makefile\357\200\272Zone.Identifier" | Bin 27 -> 0 bytes .../ahocorasick.c" | 74 ----- .../ahocorasick.h" | 31 --- .../ahotrie.c" | 160 ----------- .../ahotrie.h" | 34 --- .../constructions.c" | 109 -------- .../constructions.h" | 7 - .../input_win.c" | 68 ----- .../linked_list.c" | 209 -------------- .../linked_list.h" | 28 -- .../middlesub/BM+.c" | 180 ------------ .../middlesub/BM.h" | 17 -- .../middlesub/grpwk.c" | 156 ----------- .../middlesub/grpwk.h" | 9 - .../middlesub/itoi.c" | 98 ------- .../middlesub/itoi.h" | 9 - .../queue.c" | 52 ---- .../queue.h" | 25 -- .../string_info.h" | 13 - 37 files changed, 14 insertions(+), 2192 deletions(-) delete mode 100644 BC_readme.txt delete mode 100644 CMakeLists.txt delete mode 100644 a.out delete mode 100644 analyze.py delete mode 100644 example/BM+.c delete mode 100644 example/BM.h delete mode 100644 example/grpwk.c delete mode 100644 example/grpwk.h delete mode 100644 itoi/grpwk.c delete mode 100644 itoi/grpwk.h delete mode 100644 itoi/itoi.c delete mode 100644 itoi/itoi.h delete mode 100644 out.txt delete mode 100644 test_main.c rename queue_test.c => test_queue.c (100%) delete mode 100644 "\346\217\220\345\207\272\347\224\250/Makefile\357\200\272Zone.Identifier" delete mode 100644 "\346\217\220\345\207\272\347\224\250/ahocorasick.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/ahocorasick.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/ahotrie.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/ahotrie.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/constructions.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/constructions.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/input_win.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/linked_list.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/linked_list.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/BM+.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/BM.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/grpwk.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/grpwk.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/itoi.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/middlesub/itoi.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/queue.c" delete mode 100644 "\346\217\220\345\207\272\347\224\250/queue.h" delete mode 100644 "\346\217\220\345\207\272\347\224\250/string_info.h" diff --git a/.gitignore b/.gitignore index 1c1a0ce..5327252 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,18 @@ +# exec files grpwk distance result -*.sh -!compile.sh -*.py -!analyze.py -.*/ *.o Makefile +*.exe +*.out -ahocorasick/ -*.vscode -*.o -*.exe \ No newline at end of file +# analyze and others +*.py + +# shell scripts +*.sh +!compile.sh + +# for vscode users +*.vscode \ No newline at end of file diff --git a/BC_readme.txt b/BC_readme.txt deleted file mode 100644 index 1d66921..0000000 --- a/BC_readme.txt +++ /dev/null @@ -1,252 +0,0 @@ -要点まとめ - -変更点: -s_iのconst修飾子を除外(ソートの必要性があるため) -t_outの型をchar型からstring_out型に変更(既に一致済のs_iに関する情報を持っておきたかった) - -BM.cの動作はボイヤームーアとほぼ同じだが虫食いのため微妙に違う動作をする。 -そのためソースコードがネット上に転がってるものとだいぶ違うことに注意。 -例えば -t:abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_0:abcddbcdbcbaaaabcccaabaaada -s_1:bdaabaadaacbdbcaad -s_2:.... -のとき、以下のような動作をする。 -ここで、t_idはt_inにおけるs_iの最後尾,comp_varはs_iのどこを比較しているかをあらわしている。 -15文字以上一致したらそこで比較を打ち切り成功探索とみなしている。 - - -udemegane@DESKTOP-K5R8CJ6:~/work/grpwk/example$ ./a.out -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:0 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:1 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:2 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:3 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:4 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:5 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:6 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:7 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:8 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:9 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:10 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:11 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:12 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:13 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:14 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:15 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i:abcddbcdbcbaaaabcccaabaaada -cmp: ^ -t_id:26 comp_var:16 - -Detected the exact position of s_i!! -Before s_i assignment:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -After s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - - -Whether or not already matched|character:c -Caution|Already matched:Character is not 'x',shifts s_i position -out:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:44 comp_var:0 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:44 comp_var:1 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:44 comp_var:2 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:44 comp_var:3 - -Shift s_i by 1 - -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:45 comp_var:0 - -Shift s_i by 1 - -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:46 comp_var:0 - -Shift s_i by 1 - -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:47 comp_var:0 - -Shift s_i by 3 - -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:50 comp_var:0 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:50 comp_var:1 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:50 comp_var:2 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:50 comp_var:3 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:50 comp_var:4 - -Shift s_i by 4 - -Whether or not already matched|character:x -Did not match -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:0 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:1 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:2 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:3 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:4 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:5 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:6 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:7 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:8 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:9 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:10 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:11 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:12 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:13 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:14 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:15 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:16 -t :abcddxxxxcbaxxabcccaabaaadaaaaabcbxxxbdaabaadaacxxxxxaddaaadabbxxxdaadadbcbxxxxaaadaadada -s_i: bdaabaadaacbdbcaad -cmp: ^ -t_id:54 comp_var:17 - -Detected the exact position of s_i!! -Before s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -After s_i assignment:abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxbdaabaadaacbdbcaadxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - - -BM complete: abcddbcdbcbaaaabcccaabaaadaxxxxxxxxxxbdaabaadaacbdbcaadxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - -It continues... \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 507c6c6..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.15) -project(grpwk C) - -set(CMAKE_C_STANDARD 99) - -add_executable(grpwk ./middlesub linked_list.c linked_list.h string_info.h input_win.c example/BM.h example/grpwk.h example/Algorithm_template.c constructions.c constructions.h example/BM.c example/BM+.c example/test.c example/Speedtest.c example/BM_temp.c example/BM_temp2.c example/adeumeru.c) \ No newline at end of file diff --git a/a.out b/a.out deleted file mode 100644 index 05a48db6e492ff6cb59b5682e1119d4b794331fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12696 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 DdsB2I diff --git a/analyze.py b/analyze.py deleted file mode 100644 index b237ec2..0000000 --- a/analyze.py +++ /dev/null @@ -1,120 +0,0 @@ -def print_table(counter): - labels = sorted(counter[0].keys()) - data = [[d[l] if l in d else 0 for l in labels] for d in counter] - max_len = max(max([[len(str(a)) for a in d] for d in data])) - table = [[f'dat{i}:'] for i in range(5)] - table.insert(0, [' '] + [f'{l:>{max_len}}' for l in labels]) - for i, l in enumerate(data): - table[i+1].extend([f'{d:>{max_len}}' for d in l]) - for l in table: - print('\t'.join(l)) - -def total_alph_counter(): - print('total_alph_counter') - counter = [{} for i in range(5)] - for i, d in enumerate(counter): - with open(f'data/dat{i}_ref', 'r') as f: - for s in f.read(): - d.setdefault(s, 0) - d[s] += 1 - print_table(counter) - -# total_alph_counter() - -def sep_len(): - print('sep_len') - counter = [{} for i in range(5)] - for i, d in enumerate(counter): - with open(f'data/dat{i}_in', 'r') as f: - for s in f.readlines()[1:]: - slen = len(s.rstrip('\n')) - # if slen > 20: - # slen = 100 - d.setdefault(slen, 0) - d[slen] += 1 - print([max(d.keys()) for d in counter]) - print_table(counter) - -# sep_len() - -def mat(): - import matplotlib.pyplot as plt - import numpy as np - print('matplotlib') - x = [i+1 for i in range(85)] - y = [3902, 3686, 3282, 2947, 2767, 2380, 2173, 1896, 1715, 1571, 1382, 1288, 1104, 1044, 922, 821, 716, 699, 547, 520, 492, 463, 389, 360, 332, 287, 270, 220, 193, 184, 168, 146, 140, 107, 109, 91, 84, 85, 66, 66, 57, 58, 46, 52, 37, 33, 25, 19, 22, 24, 25, 23, 13, 21, 15, 10, 6, 7, 10, 11, 8, 4, 5, 7, 1, 7, 4, 3, 3, 9, 1, 3, 1, 1, 3, 2, 2, 3, 1, 1, 3, 1, 2, 1, 3] - print(len(y)) - plt.plot(np.array(x), np.array(y), label='sep_len') - plt.legend() - plt.show() - -# mat() - -def x_len(): - print('x_len') - counter = [{} for i in range(5)] - for i, d in enumerate(counter): - with open(f'data/dat{i}_in', 'r') as f: - c = 0 - for s in f.read().split()[0]: - if s == 'x': - c += 1 - else: - if c < 1: - continue - d.setdefault(c, 0) - d[c] += 1 - c = 0 - import matplotlib.pyplot as plt - plt.plot(sorted(counter[i].keys()), [counter[i][k] for k in sorted(counter[i].keys())]) - plt.show() - print_table(counter) - -x_len() - -def t_to_s_rate(): - print('t_to_s_rate') - counter = [{} for i in range(5)] - for i, d in enumerate(counter): - with open(f'data/dat{i}_in', 'r') as f: - s = f.read().split() - d['tlen'] = len(s[0]) - d['slen'] = sum([len(c) for c in s[1:]]) - d['ratio'] = d['slen'] / d['tlen'] - print_table(counter) - -# t_to_s_rate() - -def t_to_x_rate(): - print('t_to_x_rate') - counter = [{} for i in range(5)] - for i, d in enumerate(counter): - with open(f'data/dat{i}_in', 'r') as f: - s = f.read().split()[0] - d['t\'len'] = len(s) - d['xcount'] = sum([c == 'x' for c in s]) - print_table(counter) - -# t_to_x_rate() - -def duplication(): - for i in range(5): - with open(f'data/dat{i}_ref', 'r') as f: - t = f.read() - with open(f'data/dat{i}_in', 'r') as f: - s = f.read().split()[1:] - t_count = {} - s_count = {} - for c in t: - t_count.setdefault(c, 0) - t_count[c] += 1 - for si in s: - for c in si: - s_count.setdefault(c, 0) - s_count[c] += 1 - - for k in t_count.keys(): - if t_count[k] != s_count[k]: - print(k) - -# duplication() diff --git a/compile.sh b/compile.sh index 46604d7..2147102 100644 --- a/compile.sh +++ b/compile.sh @@ -12,7 +12,7 @@ TCASE=0 # dat${TCASE}_inを参照(テストケースの選択) # 使い方の説明 usage_exit() { - echo "Usage: $0 [-f (-fast: no warning)] [-d