diff --git a/CMakeLists.txt b/CMakeLists.txt index 69d9873..9222de0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,8 @@ include_directories(/usr/include) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=x86-64-v3" CACHE STRING "Set C Compiler Flags to use x86 feature level V3" FORCE) # set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -I -march=x86-64-v3" CACHE STRING "Set C++ Compiler Flags to use x86 feature level V3" FORCE) -set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS} -Ofast -flto") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -Ofast -flto") +set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS} -O3 -flto") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS} -O3 -flto") set(SOURCES include/hashmap.h diff --git a/homework_11 b/homework_11 index eb83d4e..2e7b461 100755 Binary files a/homework_11 and b/homework_11 differ diff --git a/include/clock.h b/include/clock.h index 2837b23..6ff7543 100644 --- a/include/clock.h +++ b/include/clock.h @@ -1,13 +1,13 @@ #define clock_start usize freq=0;\ u64 begin=rdtsc_64bits(); -#define clock_end u64 end=rdtsc_64bits(); \ - printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq); +#define clock_end u64 end=rdtsc_64bits(); + // printf(" execute cycle(s) %llu, %zu operation(s) take place!\n",end-begin,freq); -#define record_start u64 r_begin=rdtsc_64bits(); -#define record_end(x) output_csv(x,r_begin); +// #define record_start u64 r_begin=rdtsc_64bits(); +// #define record_end(x) output_csv(x,r_begin); -// #define record_start ; -// #define record_end(x) ; +#define record_start ; +#define record_end(x) ; unsigned long long int rdtsc_64bits(); void output_csv(char * filename,unsigned long long int old); \ No newline at end of file diff --git a/include/linklist.h b/include/linklist.h index 653d066..4aa6e12 100644 --- a/include/linklist.h +++ b/include/linklist.h @@ -1,3 +1,4 @@ +#include #include "rust.h" struct Node{ @@ -8,6 +9,8 @@ struct Node{ struct Node* xor_new(void * val); struct Node* xor_next(struct Node* previous,struct Node* current); struct Node* xor_insert_front(struct Node* head,void* val); +struct Node* xor_insert_condition(struct Node* head,void* val,bool (*cmp)(void *,void *)); struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val); +void debug_head(struct Node* head); void * xor_remove(struct Node * previous,struct Node* current); usize xor_count(struct Node* head); \ No newline at end of file diff --git a/justfile b/justfile index de31b64..447047b 100644 --- a/justfile +++ b/justfile @@ -17,5 +17,10 @@ run: make VERBOSE=1 ./homework_11 +mem-test: + cmake -DCMAKE_C_FLAGS="-fsanitize=address -fstandalone-debug" -DCMAKE_BUILD_TYPE=Debug -C clang-cmakeinit.cmake . + make VERBOSE=1 + ./homework_11 + clean: rm -fr CMakeFiles build CMakeCache.txt Makefile cmake_install.cmake *.csv *.profdata *.profraw \ No newline at end of file diff --git a/src/linklist.c b/src/linklist.c index ccb9f40..874891b 100644 --- a/src/linklist.c +++ b/src/linklist.c @@ -10,18 +10,22 @@ struct Node{ __INTPTR_TYPE__ xor_; }; +// shortcut for xor_insert_mid(NULL,NULL,val) struct Node* xor_new(void * val){ struct Node* node=malloc(sizeof(struct Node)); node->xor_=(__INTPTR_TYPE__)NULL; node->val=val; + return node; } +// find next node struct Node* xor_next(struct Node* previous,struct Node* current){ if(current==NULL) return NULL; return (struct Node*)((current->xor_)^((__INTPTR_TYPE__)previous)); } +// insert node at middle, return new node struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * val){ struct Node* node=malloc(sizeof(struct Node)); if(previous!=NULL)previous->xor_^=((__INTPTR_TYPE__)current)^((__INTPTR_TYPE__)node); @@ -31,11 +35,33 @@ struct Node* xor_insert_mid(struct Node* previous,struct Node* current,void * va return node; } +// insert randomly, return new node struct Node* xor_insert_front(struct Node* head,void* val){ struct Node* next=xor_next(NULL,head); return xor_insert_mid(head,next,val); } +// insert after the element that make cmp return true, insert at front if not found, return new head +struct Node* xor_insert_condition(struct Node* head,void* val,bool (*cmp)(void *,void *)){ + if(head==NULL) return xor_new(val); + struct Node* previous=NULL; + struct Node* current=head; + + usize amount=0; + while(current!=NULL){ + struct Node* next=xor_next(previous,current); + if(!cmp(val,current->val)){ + xor_insert_mid(current,next,val); + return head; + } + previous=current; + current=next; + } + + return xor_insert_mid(NULL,head,val); +} + +// remove current, return next struct Node * xor_remove(struct Node * previous,struct Node* current){ // printf("previous: %zu, current: %zu\n",previous,current); struct Node * next=xor_next(previous,current); @@ -52,7 +78,6 @@ usize xor_count(struct Node* head){ usize amount=0; while(current!=NULL){ struct Node* next=xor_next(previous,current); - // printf("previous: %zu, current: %zu, next: %zu\n",previous,current,next); struct SizedSubmask* mask=current->val; amount++; @@ -62,6 +87,22 @@ usize xor_count(struct Node* head){ return amount; } +void debug_head(struct Node* head){ + struct Node* previous=NULL; + struct Node* current=head; + + printf("start of address:"); + while(current!=NULL){ + struct Node* next=xor_next(previous,current); + struct SizedSubmask* mask=current->val; + + printf("%zu ,",current); + + previous=current; + current=next; + } + printf("\n"); +} // int test() // { // usize my_item=10; diff --git a/src/main.c b/src/main.c index 2c2d890..ee74924 100644 --- a/src/main.c +++ b/src/main.c @@ -12,72 +12,12 @@ int main() struct State state; state.head=NULL; - printf("\x1B[34mWelcome to homework 11 (HW11)!\x1B[0m\nDoes it look very familiar?\n\n"); - input(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33minput\x1B[0m.\n"); length_distribution(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mlength_distribution\x1B[0m.\n"); segment(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msegment\x1B[0m.\n"); prefix_insert(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_insert\x1B[0m.\n"); prefix_delete(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33mprefix_delete\x1B[0m.\n"); search(&state); - printf(" [ \x1B[32mOK\x1B[0m ] Reached target \x1B[33msearch\x1B[0m.\n"); return 0; } - -// struct Point{ -// usize x; -// usize y; -// }; - -// bool eqa(void* x,void* y){ -// struct Point* a=x; -// struct Point* b=y; -// return (a->x==b->x)&&(a->y==b->y); -// } -// usize hashera(void* a){ -// struct Point* p=a; -// return (p->x)+(p->y)/2; -// } - -// int main() -// { -// struct HashMap map; -// hash_new(&map,hashera,eqa); - -// // struct Point pa; -// // usize va=2; -// // pa.x=2; -// // pa.y=7; -// // struct Point pb; -// // usize vb=3; -// // pb.x=1; -// // pb.y=9; -// // hash_insert(&map,&pa,&va); -// // hash_insert(&map,&pb,&vb); - -// // printf("pa has address of %zu\npb has address of %zu\n",&pa,&pb); - -// // usize * assert=hash_get(&map,&pb); -// // printf("address: %zu\n",assert); -// // printf("value: %zu\n",*assert); - - -// for(usize i=0;isize); -// // for(usize j=0;jlist[j].key; -// // struct Node* ll=entry->list[j].val; -// // // usize count=xor_count(ll); -// // printf("one entry\n"); -// // // printf("There are _ prefix in group %u\n",mask->mask.raw); -// // } -// } -// return 0; -// } \ No newline at end of file diff --git a/src/rust.c b/src/rust.c index 98bdcfa..fcfdec8 100644 --- a/src/rust.c +++ b/src/rust.c @@ -12,7 +12,7 @@ void panic(char * msg){ fprintf(stderr," [\x1B[31mERROR\x1B[0m ] %s\n",msg); - exit(1); + *NULL; } void log_warn(char * msg){ fprintf(stderr," [ \x1B[33mWARN\x1B[0m ] %s\n",msg); diff --git a/src/state.c b/src/state.c index 2f3d95c..cf0268b 100644 --- a/src/state.c +++ b/src/state.c @@ -27,11 +27,11 @@ usize parse_number(char** cstr_ptr){ } usize display_submask(struct SizedSubmask *mask){ - printf("%3hd.%hd.%hd.%hd/%zu",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0],mask->len); + printf("%hd.%hd.%hd.%hd/%zu",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0],mask->len); } usize display_ip(struct SizedSubmask *mask){ - printf("%3hd.%3hd.%3hd.%3hd",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0]); + printf("%hd.%hd.%hd.%hd",mask->mask.mask[3],mask->mask.mask[2],mask->mask.mask[1],mask->mask.mask[0]); } void parse_submask(char* cstr, struct SizedSubmask *mask){ diff --git a/src/v1.c b/src/v1.c index 5163c3f..c5d6aed 100644 --- a/src/v1.c +++ b/src/v1.c @@ -8,21 +8,17 @@ void input(struct State* state){ FILE * table = fopen("routing_table.txt","r"); - struct Node* head=NULL; while(true){ char buffer[20]={'\0'}; fgets(buffer,20,table); if(*buffer=='\0') break; struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask)); - // printf("address of new mask: %zu\n",mask); parse_submask(buffer,mask); + if(mask<10000)printf("%zu\n",mask); - if(head==NULL)head=xor_new(mask); - else head=xor_insert_mid(NULL,head,mask); + state->head=xor_insert_mid(NULL,state->head,mask); } - - state->head=head; } void length_distribution(struct State* state){ @@ -36,13 +32,10 @@ void length_distribution(struct State* state){ struct SizedSubmask* mask=current->val; lens[mask->len]++; - // printf("address of scanning mask: %zu\n",mask); - previous=current; current=next; } - for(usize i=0;i<=32;i++){ - if(lens[i]!=0) printf(" There are %5zu prefix which have prefix len of %2zu\n",lens[i],i); - } + for(usize i=0;i<=32;i++) + printf("the number of prefixes with prefix length %zu = %zu\n",i,lens[i]); } \ No newline at end of file diff --git a/src/v2.c b/src/v2.c index 7059cb1..a26a3fc 100644 --- a/src/v2.c +++ b/src/v2.c @@ -14,55 +14,89 @@ bool eq(void* a,void* b){ return mask_a->mask.raw==mask_b->mask.raw; } +bool cmp(void* a,void* b){ + struct SizedSubmask* mask_a=a; + struct SizedSubmask* mask_b=b; + return mask_a->mask.raw>mask_b->mask.raw;// for debug +} + usize hasher(void* a){ struct SizedSubmask* mask=a; return mask->mask.raw; } +void print_binary(usize j){ + for(size_t i=1;i<=D;i++){ + printf("%s",(0==(j&(1<<(D-i))))?"0":"1"); + } +} + // std::collections::HashMap> void segment(struct State* state){ - printf(" \'d\' is %2d, and empty group are skipped!\n",D); - state->hashmap=malloc(sizeof(struct HashMap)); hash_new(state->hashmap,hasher,eq); - struct Node* previous=NULL; struct Node* current=state->head; + + state->head=NULL; while (current!=NULL){ struct SizedSubmask* mask= current->val; struct SizedSubmask* ip=clone_submask(mask); + current=xor_remove(NULL,current); if(reduce_submask(mask)){ - current=xor_remove(previous,current); - struct Node* ll=hash_get(state->hashmap,mask); - if(ll==NULL){ - struct Node* ll=xor_new(ip); - hash_insert(state->hashmap,mask,ll); - }else{ - xor_insert_front(ll,ip); - free(mask); - } + struct Node* ll=hash_pop(state->hashmap,mask); + struct Node* new=xor_insert_mid(NULL,ll,ip); + hash_insert(state->hashmap,mask,new); }else{ + state->head=xor_insert_condition(state->head,ip,cmp); + free(mask); + } + } + + // C suck! we need iterator! + for(usize i=0;i<(1<hashmap,&mask); + struct Node* previous=NULL; + + while(current!=NULL){ struct Node* next=xor_next(previous,current); + + printf(" ---> | "); + display_ip(current->val); + printf(" |"); + previous=current; current=next; - free(ip); } + printf("\n"); } - state->head=previous; + { + printf("--------special group--------\n"); - for(usize i=0;ihashmap->entry+i; - for(usize j=0;jsize;j++){ - struct SizedSubmask* mask=entry->list[j].key; - struct Node* ll=entry->list[j].val; - usize count=xor_count(ll); - if(count!=0){ - printf(" There are %5zu prefix in group %10u (",count,mask->mask.raw); - display_submask(mask); - printf(")\n"); - } + struct Node* current=state->head; + struct Node* previous=NULL; + + while(current!=NULL){ + struct Node* next=xor_next(previous,current); + + display_ip(current->val); + printf("\n"); + + previous=current; + current=next; } + + printf("-----------------------------\n"); } + } \ No newline at end of file diff --git a/src/v3.c b/src/v3.c index bff19d8..3467c3f 100644 --- a/src/v3.c +++ b/src/v3.c @@ -13,35 +13,41 @@ bool eq_v3(void* a,void* b){ return mask_a->mask.raw==mask_b->mask.raw; } +// remove match element, return new head struct Node* xor_remove_match(struct Node* head,void* target,bool (*eq)(void *,void *)){ struct Node* previous=NULL; struct Node* current=head; + struct Node* next=NULL; while(current!=NULL){ - struct Node* next=xor_next(previous,current); if(eq(current->val,target)){ free(current->val); - xor_remove(previous,current); + next=xor_remove(previous,current); break; } + struct Node* next=xor_next(previous,current); + previous=current; current=next; } - if(previous==NULL) return xor_next(previous,current); - return NULL; + if(previous==NULL) return next; + else return head; } bool xor_contain(struct Node* head,void* target,bool (*eq)(void *,void *)){ struct Node* previous=NULL; struct Node* current=head; + usize round=0; while(current!=NULL){ + // if(current<((usize)100000)) break; + // printf("current: %zu, previous: %zu, round: %zu\n",current,previous, ++round); struct Node* next=xor_next(previous,current); if(eq(current->val,target)){ - return false; + return true; } previous=current; current=next; } - return true; + return false; } void prefix_insert(struct State* state){ @@ -61,20 +67,11 @@ void prefix_insert(struct State* state){ record_start if(reduce_submask(mask)){ - struct Node* ll=hash_get(state->hashmap,mask); - if(ll==NULL){ - struct Node* ll=xor_new(ip); - hash_insert(state->hashmap,mask,ll); - }else{ - xor_insert_front(ll,ip); - free(mask); - } - }else{ - free(ip); - if(state->head==NULL)state->head=xor_new(mask); - else state->head=xor_insert_mid(NULL,state->head,mask); - } - + struct Node* ll=hash_pop(state->hashmap,mask); + struct Node* new=xor_insert_mid(NULL,ll,ip); + hash_insert(state->hashmap,mask,new); + }else state->head=xor_insert_mid(NULL,state->head,ip); + record_end("prefix_insert.csv") freq++; @@ -93,7 +90,6 @@ void prefix_delete(struct State* state){ fgets(buffer,20,table); if(*buffer=='\0') break; - struct SizedSubmask* mask=malloc(sizeof(struct SizedSubmask)); parse_submask(buffer,mask); struct SizedSubmask* ip=clone_submask(mask); @@ -102,19 +98,10 @@ void prefix_delete(struct State* state){ if(reduce_submask(mask)){ struct Node* ll=hash_pop(state->hashmap,mask); - if(ll==NULL) { - log_warn("removal fail, cannot find index!"); - goto drop; - } struct Node* new_head=xor_remove_match(ll,ip,eq_v3); - if(new_head==NULL) hash_insert(state->hashmap,mask,ll); - else hash_insert(state->hashmap,mask,new_head); + if(new_head!=NULL) hash_insert(state->hashmap,mask,new_head); }else{ struct Node* ll=state->head; - if(ll==NULL) { - log_warn("removal fail, cannot find index!"); - goto drop; - } struct Node* new_head=xor_remove_match(ll,ip,eq_v3); if(new_head!=NULL) state->head=new_head; } @@ -122,9 +109,7 @@ void prefix_delete(struct State* state){ record_end("prefix_delete.csv") - drop: free(ip); - free(mask); } clock_end @@ -154,11 +139,10 @@ void search(struct State* state){ record_end("search.csv") - printf(" submask: "); - display_ip(ip); + debug_head(ll); - if (xor_contain(ll,ip,eq_v3)) printf(" can be found among entries\n"); - else printf(" cannot be found among entries\n"); + if (xor_contain(ll,ip,eq_v3)) printf("successful\n"); + else printf("failed\n"); free(ip); free(mask); diff --git a/trace_file.txt b/trace_file.txt index 3a4f2ef..296974b 100644 --- a/trace_file.txt +++ b/trace_file.txt @@ -1,1364 +1,7 @@ -1.0.0.0 -51.154.241.157 -51.203.21.93 -4.0.0.0 -4.1.18.0 -4.2.62.0 -4.2.63.0 -4.2.90.0 -4.2.124.0 -4.2.124.0 -4.6.0.0 -4.6.0.0 -4.6.4.0 -4.6.8.0 -4.6.62.0 -4.6.68.0 -4.6.72.0 -4.6.76.0 -4.6.80.0 -4.6.81.0 -4.6.82.0 -4.6.84.0 -11.143.76.221 -4.6.88.0 -14.158.187.190 -4.6.96.0 -4.6.98.0 -4.6.99.0 -4.6.100.0 -4.6.104.0 -4.6.108.0 -4.6.110.0 -4.6.112.0 -4.6.116.0 -14.92.106.205 -4.6.124.0 -4.6.125.0 -6.169.83.120 -4.6.128.0 -4.6.132.0 -4.6.136.0 -4.6.138.0 -4.6.140.0 -4.6.144.0 -4.6.148.0 -4.6.152.0 -4.6.153.0 -56.181.45.175 -4.6.156.0 -4.6.160.0 -4.6.164.0 -4.6.166.0 -4.6.168.0 -25.91.200.248 -4.6.172.0 -4.6.176.0 -4.17.225.0 -4.17.226.0 -4.17.251.0 -4.17.252.0 -4.21.252.0 -4.23.180.0 -4.25.133.40 -4.36.200.0 -4.51.0.0 -4.51.0.0 -4.51.8.0 -4.51.12.0 -25.240.207.106 -4.52.0.0 -4.54.0.0 -4.54.8.0 -4.54.12.0 -4.54.22.0 -4.54.24.0 -4.54.28.0 -4.54.32.0 -4.54.36.0 -4.54.48.0 -4.54.62.0 -4.54.64.0 -4.54.68.0 -11.243.89.193 -56.141.191.166 -4.54.78.0 -4.54.80.0 -4.54.81.0 -4.54.82.0 -4.54.84.0 -0.157.23.12 -4.54.98.0 -4.54.106.0 -4.54.116.0 -4.54.120.0 -4.54.124.0 -4.54.128.0 -4.54.140.0 -4.54.144.0 -4.54.148.0 -4.54.152.0 -4.54.156.0 -4.54.160.0 -4.54.200.0 -4.54.207.0 -4.54.212.0 -4.54.216.0 -9.176.151.131 -4.54.220.0 -4.54.224.0 -4.54.226.0 -4.54.228.0 -4.54.232.0 -4.54.233.0 -4.54.234.0 -4.54.236.0 -4.54.240.0 -4.54.249.0 -4.54.250.0 -4.54.254.0 -4.55.0.0 -4.56.0.0 -4.56.204.0 -4.56.205.0 -4.56.216.0 -4.56.218.0 -4.56.222.0 -4.56.223.0 -4.56.232.0 -4.56.240.0 -4.56.242.0 -4.56.244.0 -4.56.246.0 -4.56.248.0 -4.56.250.0 -4.56.252.0 -4.56.253.0 -4.57.0.0 -4.57.0.0 -4.57.4.0 -4.57.6.0 -4.57.16.0 -4.57.20.0 -4.57.22.0 -4.57.24.0 -4.57.28.0 -51.61.140.47 -4.57.33.0 -4.57.34.0 -4.57.36.0 -0.119.68.198 -0.213.172.191 -4.57.48.0 -4.57.52.0 -4.57.54.0 -4.57.55.0 -9.76.115.113 -4.57.60.0 -4.57.62.0 -54.112.249.145 -51.248.241.6 -4.57.68.0 -4.57.72.0 -4.57.76.0 -4.57.80.0 -4.57.82.0 -4.57.84.0 -4.57.85.0 -4.57.86.0 -4.57.88.0 -4.57.92.0 -4.57.94.0 -4.57.96.0 -4.57.100.0 -4.57.104.0 -4.57.108.0 -4.57.112.0 -4.57.116.0 -4.57.117.0 -4.57.118.0 -4.57.120.0 -4.57.124.0 -4.57.126.0 -4.57.128.0 -4.57.132.0 -4.57.136.0 -4.57.140.0 -4.57.142.0 -4.57.143.0 -4.57.148.0 -20.101.33.255 -9.15.195.146 -4.57.154.0 -4.57.156.0 -4.57.171.0 -4.57.176.0 -4.57.180.0 -4.57.184.0 -4.57.186.0 -4.57.188.0 -22.218.210.34 -4.57.196.0 -4.57.200.0 -4.57.201.0 -4.57.202.0 -4.57.204.0 -25.122.100.172 -4.57.212.0 -4.57.214.0 -4.57.216.0 -4.57.220.0 -4.57.224.0 -4.57.226.0 -4.57.228.0 -4.57.229.0 -4.57.230.0 -21.207.69.67 -4.57.236.0 -4.57.240.0 -4.57.244.0 -4.57.248.0 -4.57.250.0 -4.57.251.0 -4.57.252.0 -4.76.0.0 -4.76.4.0 -4.76.8.0 -4.76.12.0 -4.76.16.0 -4.76.20.0 -4.76.24.0 -4.76.28.0 -4.76.30.0 -51.246.36.25 -4.76.36.0 -4.76.38.0 -4.76.40.0 -29.199.216.15 -4.76.48.0 -26.25.189.92 -4.76.56.0 -19.249.59.160 -4.76.62.0 -4.78.32.0 -5.0.0.0 -6.1.0.0 -19.136.49.107 -6.3.0.0 -6.4.0.0 -6.5.0.0 -6.8.0.0 -6.9.0.0 -6.10.0.0 -6.14.0.0 -6.106.74.32 -7.0.0.0 -8.0.0.0 -10.0.0.0 -12.0.0.0 -12.0.17.0 -12.0.19.0 -12.0.28.0 -28.255.141.97 -12.0.48.0 -12.0.252.0 -12.1.83.0 -0.234.114.167 -12.1.235.0 -11.109.39.241 -12.2.6.0 -12.2.6.0 -12.2.7.0 -12.2.22.0 -12.2.35.0 -12.2.41.0 -12.2.49.0 -12.2.84.0 -12.2.86.0 -12.2.88.0 -12.2.140.0 -12.2.142.0 -29.166.11.250 -12.2.192.0 -12.3.33.0 -12.3.54.0 -12.3.62.0 -12.3.70.0 -12.3.80.0 -12.3.119.0 -12.3.123.0 -12.3.217.0 -12.3.242.0 -12.4.96.0 -12.4.96.0 -12.4.97.0 -12.4.100.0 -12.4.114.0 -29.75.144.239 -12.4.126.0 -12.4.193.0 -12.4.194.0 -12.4.196.0 -12.4.218.0 -12.4.225.0 -12.4.228.0 -12.5.16.0 -12.5.48.0 -12.5.48.0 -12.5.49.0 -12.5.50.0 -12.5.52.0 -12.5.53.0 -12.5.54.0 -12.5.56.0 -12.5.56.0 -12.5.58.0 -12.5.59.0 -12.5.60.0 -12.5.136.0 -12.5.144.0 -12.5.164.0 -12.5.165.0 -12.5.173.0 -12.5.179.0 -12.5.201.0 -12.6.9.0 -12.6.21.0 -12.6.89.0 -12.6.95.0 -12.6.195.0 -19.151.160.66 -12.6.208.0 -12.7.51.0 -12.7.170.0 -12.8.7.0 -12.8.56.0 -12.8.130.0 -12.8.135.0 -12.8.167.0 -12.8.177.0 -12.8.184.0 -12.8.198.0 -12.8.199.0 -12.9.136.0 -12.9.138.0 -0.146.244.75 -12.9.144.0 -12.9.207.0 -12.9.238.0 -29.47.17.134 -12.10.20.0 -12.10.83.0 -12.10.150.0 -12.10.189.0 -12.10.220.0 -12.11.130.0 -6.91.68.106 -12.11.148.0 -12.11.149.0 -12.11.150.0 -0.67.61.38 -12.11.152.0 -12.13.74.0 -12.13.78.0 -12.13.116.0 -12.13.160.0 -12.13.212.0 -12.14.89.0 -12.14.122.0 -12.14.172.0 -12.14.190.0 -12.14.232.0 -12.14.237.0 -12.14.238.0 -12.15.28.0 -12.15.46.0 -12.15.58.0 -12.15.88.0 -12.16.40.0 -12.16.41.0 -12.16.44.0 -12.16.59.0 -12.16.76.0 -12.16.120.0 -12.16.157.0 -12.16.158.0 -12.16.240.0 -12.17.11.0 -12.17.14.0 -12.17.15.0 -12.17.90.0 -12.17.123.0 -12.17.162.0 -12.17.173.0 -12.17.199.0 -12.17.202.0 -12.17.226.0 -12.18.25.0 -12.18.36.0 -12.18.36.0 -20.251.150.242 -12.18.68.0 -12.18.76.0 -12.18.77.0 -12.18.90.0 -12.18.96.0 -127.35.175.228 -12.18.120.0 -12.18.122.0 -12.18.155.0 -12.18.177.0 -12.19.55.0 -12.19.68.0 -12.19.225.0 -12.20.31.0 -12.20.40.0 -12.20.48.0 -12.20.55.0 -12.20.92.0 -12.20.127.0 -12.20.134.0 -12.20.137.0 -12.20.158.0 -12.20.166.0 -12.20.200.0 -12.20.222.0 -12.20.229.0 -12.20.249.0 -12.21.14.0 -12.21.84.0 -127.209.168.86 -12.21.85.0 -12.21.95.0 -12.21.104.0 -12.21.105.0 -12.21.132.0 -12.21.144.0 -12.21.221.0 -12.21.228.0 -12.22.30.0 -12.22.60.0 -12.22.65.0 -12.22.80.0 -12.22.165.0 -0.36.36.38 -12.22.181.0 -12.22.204.0 -12.23.26.0 -12.23.28.0 -0.188.175.40 -12.23.53.0 -56.37.139.28 -12.23.70.0 -11.85.144.26 -12.23.136.0 -12.23.142.0 -12.23.194.0 -12.24.23.0 -12.24.41.0 -12.24.44.0 -12.24.48.0 -12.24.49.0 -12.24.50.0 -12.24.56.0 -12.24.81.0 -51.103.88.10 -12.24.96.0 -12.24.105.0 -12.24.108.0 -12.24.112.0 -12.24.113.0 -12.24.114.0 -12.24.115.0 -12.24.138.0 -12.24.204.0 -12.24.250.0 -12.24.252.0 -12.25.49.0 -12.25.52.0 -12.25.79.0 -12.25.105.0 -12.25.114.0 -12.25.136.0 -12.25.185.0 -12.25.196.0 -12.25.210.0 -12.25.220.0 -12.25.232.0 -12.25.241.0 -12.25.251.0 -12.26.7.0 -56.38.39.83 -12.26.53.0 -12.26.55.0 -12.26.84.0 -12.26.86.0 -12.26.100.0 -12.26.103.0 -12.26.128.0 -12.26.136.0 -12.26.140.0 -12.26.141.0 -12.26.204.0 -12.26.226.0 -12.27.20.0 -12.27.25.0 -12.27.40.0 -12.27.40.0 -22.13.109.68 -12.27.42.0 -12.27.43.0 -12.27.88.0 -12.27.89.0 -12.27.90.0 -12.27.91.0 -12.27.129.0 -12.27.137.0 -12.27.172.0 -11.65.138.196 -12.27.217.0 -12.27.222.0 -12.28.124.0 -12.28.146.0 -12.28.148.0 -43.80.34.27 -12.28.194.0 -12.28.219.0 -12.28.242.0 -127.130.252.213 -12.29.38.0 -12.29.72.0 -12.29.100.0 -12.29.101.0 -12.29.102.0 -12.29.162.0 -12.29.181.0 -12.29.182.0 -12.29.190.0 -12.29.194.0 -12.29.230.0 -12.30.1.0 -12.30.12.0 -12.30.53.0 -12.30.62.0 -12.30.100.0 -12.30.105.0 -12.30.122.0 -12.30.157.0 -11.140.55.37 -12.30.167.0 -12.30.198.0 -12.30.205.0 -12.30.208.0 -12.30.238.0 -12.31.21.0 -12.31.24.0 -12.31.25.0 -12.31.51.0 -12.31.88.0 -12.31.97.0 -12.31.98.0 -12.31.117.0 -12.31.125.0 -22.154.95.31 -12.31.127.0 -12.31.159.0 -12.31.161.0 -12.31.202.0 -12.31.215.0 -12.32.2.0 -12.32.9.0 -12.32.72.0 -12.32.231.0 -12.32.241.0 -12.33.21.0 -12.33.69.0 -12.33.70.0 -12.33.78.0 -12.33.114.0 -12.33.115.0 -12.33.127.0 -12.33.142.0 -12.33.194.0 -12.33.195.0 -12.33.218.0 -12.34.2.0 -12.34.3.0 -12.34.8.0 -12.34.41.0 -12.34.51.0 -30.105.74.165 -12.34.68.0 -0.119.133.166 -127.35.84.169 -12.34.103.0 -12.34.121.0 -12.34.129.0 -12.34.154.0 -12.34.159.0 -12.34.172.0 -12.34.212.0 -12.34.214.0 -12.35.96.0 -12.35.139.0 -12.35.145.0 -12.35.147.0 -12.35.204.0 -12.35.206.0 -0.64.76.158 -12.36.9.0 -12.36.49.0 -12.36.75.0 -12.36.77.0 -9.41.4.221 -12.36.118.0 -12.36.133.0 -12.36.160.0 -12.36.175.0 -12.36.200.0 -12.36.203.0 -12.36.209.0 -12.36.210.0 -12.36.215.0 -12.36.216.0 -12.36.217.0 -12.36.218.0 -12.36.219.0 -12.36.227.0 -12.37.19.0 -12.37.26.0 -12.37.27.0 -12.37.28.0 -12.37.62.0 -12.37.108.0 -12.37.211.0 -12.37.226.0 -12.37.228.0 -12.37.238.0 -12.38.46.0 -12.38.93.0 -12.38.136.0 -12.38.142.0 -12.38.144.0 -12.38.145.0 -12.38.185.0 -12.38.188.0 -12.38.240.0 -12.39.65.0 -12.39.76.0 -12.39.106.0 -12.39.152.0 -12.39.154.0 -12.39.159.0 -12.39.216.0 -12.39.227.0 -12.39.230.0 -46.90.90.134 -12.40.18.0 -12.40.62.0 -12.40.114.0 -12.40.121.0 -12.40.130.0 -29.55.197.48 -12.40.140.0 -12.40.180.0 -20.87.157.59 -12.40.202.0 -12.40.212.0 -12.40.239.0 -12.41.48.0 -12.41.49.0 -12.41.50.0 -12.41.51.0 -12.41.66.0 -29.84.161.120 -12.41.110.0 -12.41.124.0 -12.41.152.0 -12.41.153.0 -12.41.154.0 -12.41.155.0 -12.41.162.0 -12.41.169.0 -47.29.229.249 -12.41.193.0 -12.41.194.0 -12.41.194.0 -12.41.195.0 -12.41.248.0 -12.41.252.0 -12.41.253.0 -12.42.50.0 -12.42.51.0 -12.42.52.0 -12.42.58.0 -12.42.59.0 -12.42.95.0 -12.42.136.0 -12.42.144.0 -12.42.169.0 -12.42.198.0 -12.43.125.0 -12.43.128.0 -12.43.128.0 -22.124.195.207 -12.43.144.0 -12.43.146.0 -12.43.216.0 -12.43.218.0 -12.44.42.0 -12.44.44.0 -12.44.152.0 -12.44.163.0 -12.44.164.0 -12.44.166.0 -34.41.36.16 -12.44.243.0 -12.44.252.0 -127.173.146.113 -12.45.21.0 -12.45.22.0 -12.45.23.0 -12.45.24.0 -12.45.26.0 -12.45.27.0 -6.130.212.199 -12.45.103.0 -12.45.108.0 -12.45.110.0 -12.45.116.0 -12.45.117.0 -12.45.121.0 -12.45.134.0 -12.45.139.0 -12.45.144.0 -12.45.146.0 -12.45.157.0 -12.45.169.0 -12.45.212.0 -12.45.237.0 -12.45.247.0 -12.45.248.0 -12.45.253.0 -12.46.6.0 -12.46.24.0 -12.46.133.0 -12.46.135.0 -12.46.160.0 -43.192.134.109 -12.46.164.0 -12.46.168.0 -12.46.181.0 -12.46.189.0 -12.46.238.0 -12.46.250.0 -12.47.33.0 -12.47.65.0 -12.47.70.0 -12.47.86.0 -21.254.83.127 -26.37.254.210 -12.47.192.0 -12.47.217.0 -12.47.220.0 -12.47.255.0 -12.64.0.0 -34.50.39.183 -12.64.96.0 -12.64.128.0 -46.117.161.26 -12.64.255.0 -12.65.0.0 -12.65.64.0 -12.65.96.0 -47.23.226.168 -12.65.192.0 -12.65.224.0 -12.65.240.0 -12.66.0.0 -12.66.32.0 -12.66.48.0 -47.110.225.188 -12.66.60.0 -12.66.63.0 -12.66.64.0 -0.120.111.131 -12.66.66.0 -12.66.67.0 -12.66.68.0 -12.66.69.0 -12.66.70.0 -12.66.71.0 -12.66.72.0 -12.66.80.0 -12.66.85.0 -12.66.86.0 -12.66.88.0 -12.66.96.0 -12.66.104.0 -12.67.0.0 -12.67.1.0 -12.67.4.0 -12.67.5.0 -12.67.6.0 -12.67.7.0 -48.205.244.197 -12.79.224.0 -12.79.228.0 -12.87.224.0 -12.87.246.0 -12.87.248.0 -12.87.250.0 -12.96.21.0 -12.96.58.0 -12.96.77.0 -14.19.227.77 -12.96.160.0 -12.96.182.0 -12.96.217.0 -12.96.228.0 -12.96.230.0 -12.96.240.0 -12.104.24.0 -12.104.35.0 -12.104.70.0 -12.104.96.0 -12.104.104.0 -12.104.108.0 -12.104.109.0 -12.104.113.0 -12.104.114.0 -12.104.119.0 -12.104.138.0 -12.104.140.0 -12.104.147.0 -12.104.226.0 -12.104.244.0 -12.105.6.0 -12.105.20.0 -12.105.24.0 -12.105.28.0 -12.105.29.0 -56.85.18.190 -34.77.221.194 -12.105.67.0 -12.105.74.0 -12.105.104.0 -12.105.115.0 -12.105.119.0 -12.105.128.0 -12.105.129.0 -12.105.148.0 -12.105.179.0 -12.105.185.0 -12.105.192.0 -12.105.216.0 -12.106.16.0 -12.106.18.0 -26.231.222.64 -12.106.30.0 -12.106.67.0 -12.106.68.0 -12.106.69.0 -12.106.70.0 -12.106.77.0 -12.106.80.0 -30.52.118.81 -12.106.130.0 -12.106.140.0 -52.215.161.59 -12.107.6.0 -12.107.13.0 -12.107.20.0 -12.107.52.0 -12.107.82.0 -12.107.130.0 -12.107.131.0 -11.151.170.146 -12.107.160.0 -12.107.180.0 -12.107.188.0 -12.107.197.0 -20.210.110.41 -12.107.232.0 -12.107.239.0 -12.107.246.0 -12.107.248.0 -12.107.250.0 -12.108.30.0 -12.108.84.0 -12.108.100.0 -12.108.101.0 -12.108.102.0 -12.108.103.0 -12.108.132.0 -12.108.140.0 -12.108.188.0 -12.108.199.0 -12.108.209.0 -12.108.212.0 -43.237.180.243 -12.108.216.0 -12.108.237.0 -12.108.254.0 -12.109.0.0 -12.109.71.0 -12.109.80.0 -12.109.85.0 -12.109.107.0 -12.109.109.0 -12.109.130.0 -29.23.193.55 -12.109.150.0 -12.109.164.0 -12.109.164.0 -12.109.166.0 -12.109.168.0 -12.109.172.0 -12.109.184.0 -12.109.202.0 -12.109.204.0 -12.109.224.0 -12.109.236.0 -12.109.237.0 -12.109.242.0 -34.4.194.59 -12.110.1.0 -12.110.2.0 -12.110.6.0 -12.110.8.0 -12.110.12.0 -12.110.19.0 -12.110.23.0 -12.110.25.0 -12.110.27.0 -12.110.40.0 -12.110.53.0 -12.110.58.0 -25.167.167.247 -12.110.144.0 -12.110.150.0 -12.110.172.0 -12.110.253.0 -12.111.19.0 -12.111.50.0 -12.111.60.0 -12.111.73.0 -12.111.138.0 -12.111.164.0 -12.111.168.0 -12.111.178.0 -12.111.181.0 -12.111.184.0 -12.111.190.0 -12.111.210.0 -12.111.214.0 -12.111.223.0 -12.125.176.22 -12.127.255.255 -11.50.208.177 -12.129.5.0 -25.107.159.121 -12.129.32.0 -12.129.64.0 -12.129.96.0 -12.129.128.0 -12.129.165.0 -54.51.93.30 -12.129.192.0 -12.129.201.0 -12.129.204.0 -12.129.226.0 -12.130.0.0 -12.130.80.0 -12.130.82.0 -54.25.187.188 -12.130.92.0 -12.144.20.0 -12.144.20.0 -12.144.21.0 -12.144.39.0 -12.144.41.0 -12.144.47.0 -12.144.49.0 -12.144.59.0 -12.144.122.0 -12.144.123.0 -127.173.21.211 -12.144.144.0 -12.144.145.0 -12.144.148.0 -12.144.152.0 -12.144.231.0 -19.17.178.68 -12.145.50.0 -12.145.65.0 -12.145.108.0 -12.145.158.0 -11.31.203.63 -12.145.208.0 -12.145.212.0 -12.145.216.0 -12.145.217.249 -12.146.1.0 -12.146.83.0 -12.146.112.0 -12.146.145.0 -0.105.249.208 -12.147.32.0 -12.147.33.0 -12.147.34.0 -12.147.35.0 -12.147.36.0 -28.182.27.96 -12.147.38.0 -12.147.39.0 -12.147.44.0 -12.147.77.0 -12.147.129.0 -12.147.148.0 -12.147.166.0 -12.148.8.0 -12.148.15.0 -12.148.16.0 -12.148.20.0 -12.148.28.0 -12.148.30.0 -12.148.48.0 -12.148.49.0 -12.148.50.0 -12.148.51.0 -12.148.67.0 -12.148.117.0 -12.148.160.0 -12.148.168.0 -12.148.169.0 -12.148.180.0 -12.148.184.0 -12.148.203.0 -12.148.204.0 -12.148.208.0 -11.179.9.108 -12.149.7.0 -12.149.13.0 -12.149.37.0 -12.149.50.0 -12.149.50.0 -12.149.51.0 -12.149.52.0 -12.149.79.0 -6.241.137.60 -12.149.112.0 -12.149.144.0 -12.149.149.0 -12.149.160.0 -12.149.165.0 -12.149.167.0 -12.149.230.0 -12.149.238.0 -20.161.181.109 -12.150.40.0 -12.150.48.0 -12.150.57.0 -12.150.60.0 -12.150.233.0 -12.150.242.0 -12.150.246.0 -12.150.254.0 -12.151.33.0 -12.151.34.0 -12.151.64.0 -12.151.102.0 -12.151.122.0 -12.151.126.0 -12.151.229.0 -12.151.230.0 -12.151.231.0 -12.152.10.0 -12.152.18.0 -12.152.100.0 -12.152.102.0 -12.152.104.0 -12.152.107.0 -12.152.121.0 -12.152.122.0 -12.152.126.0 -12.152.144.0 -12.152.160.0 -12.152.164.0 -12.152.165.0 -12.152.172.0 -12.153.0.0 -12.153.8.0 -12.153.20.0 -12.153.50.0 -12.153.80.0 -12.153.83.0 -12.153.131.0 -12.153.146.0 -12.153.192.0 -12.153.224.0 -12.153.244.0 -12.154.34.0 -12.154.52.0 -12.154.84.0 -29.86.91.54 -21.81.127.20 -12.154.116.0 -12.154.121.0 -12.154.195.0 -12.154.200.0 -12.154.214.0 -12.154.216.0 -47.244.209.194 -12.155.49.0 -12.155.50.0 -12.155.102.0 -12.155.106.0 -12.155.116.0 -12.155.119.0 -12.155.124.0 -12.155.132.0 -26.43.115.246 -12.155.154.0 -12.155.155.0 -12.155.170.0 -12.155.183.0 -12.155.193.0 -12.155.208.0 -12.155.246.0 -9.245.89.211 -12.158.34.0 -12.158.34.0 -12.158.36.0 -12.158.38.0 -12.158.80.0 -12.158.102.205 -21.64.44.97 -12.158.136.0 -12.158.148.0 -12.158.153.0 -12.158.162.0 -12.158.168.0 -12.158.202.0 -12.158.239.0 -46.149.32.231 -12.159.53.0 -12.159.54.0 -12.159.55.0 -12.159.64.0 -12.159.80.0 -12.159.92.0 -12.159.167.0 -12.159.184.0 -12.159.186.0 -26.167.188.54 -12.159.188.0 -22.86.81.44 -12.159.230.0 -12.159.244.0 -12.160.16.0 -12.160.19.0 -12.160.33.0 -12.160.34.0 -30.140.18.163 -54.151.28.133 -12.160.72.0 -12.160.109.0 -12.160.128.0 -12.160.129.0 -12.160.130.0 -12.160.131.0 -12.160.132.0 -12.160.133.0 -12.160.134.0 -12.160.135.0 -29.171.96.169 -12.160.158.0 -12.160.186.0 -12.160.207.0 -12.160.224.0 -12.160.232.0 -12.161.8.0 -12.161.49.0 -12.161.66.0 -12.161.68.0 -12.161.72.0 -12.161.104.0 -12.161.114.0 -28.102.117.235 -12.161.133.0 -12.161.199.0 -34.47.255.192 -12.161.222.0 -12.161.224.0 -12.161.242.0 -25.91.62.155 -12.161.254.0 -14.21.111.221 -12.162.8.0 -12.162.34.0 -12.162.36.0 -12.162.52.0 -12.162.53.0 -12.162.57.0 -12.162.61.0 -40.116.59.100 -12.162.114.0 -12.162.114.0 -12.162.136.0 -12.162.137.0 -12.162.138.0 -12.162.139.0 -12.162.142.0 -12.162.152.0 -12.162.153.0 -12.162.154.0 -12.162.155.0 -12.162.160.0 -12.162.216.0 -12.163.2.0 -12.163.46.0 -12.163.56.0 -12.163.64.0 -12.163.68.0 -12.163.88.0 -12.163.112.0 -12.163.140.0 -21.59.183.243 -54.149.71.92 -12.163.170.0 -12.163.174.0 -12.163.180.0 -12.163.193.0 -12.163.198.0 -12.164.4.0 -12.164.6.0 -12.164.8.0 -12.164.12.0 -12.164.64.0 -12.164.76.0 -12.164.96.0 -12.164.144.0 -12.164.224.0 -12.164.224.0 -12.164.227.0 -12.164.228.0 -12.164.228.0 -12.164.240.0 -12.164.244.0 -12.164.246.0 -12.164.247.0 -12.165.25.0 -12.165.48.0 -12.165.56.0 -12.165.144.0 -12.165.182.0 -12.165.184.0 -12.165.192.0 -12.165.196.0 -12.166.64.0 -12.166.88.0 -12.166.98.0 -9.84.215.219 -12.166.196.0 -12.166.200.0 -14.117.222.239 -12.166.202.0 -12.166.203.0 -12.166.204.0 -34.28.109.107 -12.166.206.0 -12.166.207.0 -12.166.208.0 -12.166.216.0 -12.166.216.0 -12.166.217.0 -6.101.100.108 -12.166.237.0 -12.166.240.0 -12.166.243.0 -12.167.68.0 -12.167.70.0 -12.167.74.0 -12.167.75.0 -12.167.76.0 -56.216.67.42 -12.167.148.0 -12.167.149.0 -12.167.150.0 -12.167.160.0 -12.167.172.0 -28.158.216.140 -12.167.225.0 -12.168.70.0 -12.168.73.0 -12.168.77.0 -12.168.121.0 -12.168.147.0 -12.168.164.0 -12.168.165.0 -12.168.166.0 -12.168.167.0 -12.168.168.0 -12.169.96.0 -12.169.104.0 -12.169.106.0 -12.169.129.0 -21.211.137.60 -12.169.208.0 -12.170.0.0 -12.170.3.0 -12.170.32.0 -12.170.34.0 -12.170.156.0 -43.111.177.205 -54.27.138.54 -12.171.190.0 -12.171.193.0 -12.171.194.0 -12.171.195.0 -12.172.96.0 -12.172.97.0 -12.172.98.0 -6.132.146.195 -12.173.48.0 -12.173.60.0 -12.173.194.0 -12.173.196.0 -12.173.209.0 -12.173.227.0 -12.173.235.0 -12.174.34.0 -12.174.36.0 -12.174.87.0 -12.174.210.0 -12.174.224.0 -12.175.40.0 -12.175.48.0 -12.175.115.0 -12.175.224.0 -12.176.100.0 -48.124.146.106 -12.176.228.0 -12.177.20.0 -12.177.32.0 -12.177.68.0 -12.178.96.0 -12.178.144.0 -12.179.117.0 -12.179.128.0 -12.180.104.0 -12.180.240.0 -12.180.242.0 -12.181.64.0 -12.194.239.0 -12.194.240.0 -12.223.2.0 -12.223.4.0 -12.223.6.0 -12.232.104.221 -12.242.16.0 +13.8.128.0 +12.242.18.0 +12.242.17.0 +12.242.17.0 12.242.17.0 12.242.18.0 13.0.0.0