diff --git a/inc/Maat_rule.h b/inc/Maat_rule.h index e31d68a..f7399c1 100644 --- a/inc/Maat_rule.h +++ b/inc/Maat_rule.h @@ -13,11 +13,9 @@ */ #ifndef H_MAAT_RULE_H_INCLUDE #define H_MAAT_RULE_H_INCLUDE - #ifndef __cplusplus #error("This file should be compiled with C++ compiler") #endif - #include "stream.h" enum MAAT_CHARSET { @@ -26,7 +24,13 @@ enum MAAT_CHARSET CHARSET_BIG5, CHARSET_UNICODE, CHARSET_UTF8, // 4 - CHARSET_BIN //5 + CHARSET_BIN, //5 + CHARSET_UNICODE_ASCII_ESC, // Unicode Escape format, prefix backslash-u hex, e.g. "\u627;" + CHARSET_UNICODE_ASCII_ALIGNED,//Unicode Escape format, prefix backslash-u with 4 bytes aligned, e.g. "\u0627" + CHARSET_UNICODE_NCR_DEC, //SGML Numeric character reference,decimal base, e.g. "ا" + CHARSET_UNICODE_NCR_HEX, //SGML Numeric character reference,hexdecimal base, e.g. "ا" + CHARSET_URL_ENCODE_GB2312, //URL encode with GB2312, e.g. the chinese word "china" was encoded to %D6%D0%B9%FA + CHARSET_URL_ENCODE_UTF8 //11, URL encode with UTF8,e.g. the chinese word "china" was encoded to %E4%B8%AD%E5%9B%BD }; enum MAAT_ACTION { @@ -113,17 +117,37 @@ struct Maat_hit_detail_t struct Maat_region_pos_t region_pos[MAAT_MAX_HIT_RULE_NUM]; }; //--------------------HITTING DETAIL DESCRIPTION END + +//Abondon interface ,left for compatible. Maat_feather_t Maat_summon_feather(int max_thread_num, const char* table_info_path, const char* ful_cfg_dir, const char* inc_cfg_dir, - void*logger); - + void*logger);//MESA_handle_logger +//Abondon interface ,left for compatible. Maat_feather_t Maat_summon_feather_json(int max_thread_num, const char* table_info_path, const char* json_rule, void* logger); +Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* logger); +int Maat_initiate_feather(Maat_feather_t feather); + +enum MAAT_INIT_OPT +{ + MAAT_OPT_SCANDIR_INTERVAL_MS=1, //VALUE is interger,SIZE=sizeof(int). DEFAULT:1,000 milliseconds. + MAAT_OPT_EFFECT_INVERVAL_MS, //VALUE is interger,SIZE=sizeof(int). DEFAULT:60,000 milliseconds. + MAAT_OPT_FULL_CFG_DIR, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_INC_CFG_DIR, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_JSON_FILE_PATH, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_STAT_ON, //VALUE is indifferent,SIZE is indifferent.MAAT_OPT_STAT_FILE_PATH must be set.Default: stat OFF. + MAAT_OPT_PERF_ON, //VALUE is indifferent,SIZE is indifferent.MAAT_OPT_STAT_FILE_PATH must be set.Default: stat OFF. + MAAT_OPT_STAT_FILE_PATH, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_SCAN_DETAIL //VALUE is interger,SIZE=sizeof(int). 0: not return any detail;1: return hit pos, not include regex grouping; + // 2 return hit pos and regex grouping pos;DEFAULT:2 +}; +//return -1 if failed, return 0 on success; +int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const void* value,int size); void Maat_burn_feather(Maat_feather_t feather); //return table_id(>=0) if success,otherwise return -1; @@ -135,7 +159,12 @@ int Maat_table_callback_register(Maat_feather_t feather,short table_id, Maat_finish_callback_t *finish,//u_para void* u_para); - +enum MAAT_SCAN_OPT +{ + MAAT_SET_SCAN_DISTRICT=1 //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1.DEFAULT: no default. +}; +//return 0 if success, return -1 when failed; +int Maat_set_scan_status(Maat_feather_t feather,scan_status_t* mid,enum MAAT_SCAN_OPT type,const void* value,int size); //Return hit rule number, return -1 when error occurs,return -2 when hit current region //mid MUST set NULL before fist call @@ -184,10 +213,5 @@ void Maat_stream_scan_digest_end(stream_para_t* stream_para); void Maat_clean_status(scan_status_t* mid); -#define MAAT_OPT_SCANDIR_INTERVAL_MS 1 //opt value is interger,size=sizeof(int),1,000 milliseconds as default -#define MAAT_OPT_EFFECT_INVERVAL_MS 2 //opt value is interger,size=sizeof(int),60,000 milliseconds as default -//return -1 if failed, return 0 on success; -int Maat_set_feather_opt(Maat_feather_t feather,int type,void* value,int size); - #endif // H_MAAT_RULE_H_INCLUDE diff --git a/src/inc_internal/mesa_fuzzy.h b/inc/mesa_fuzzy.h similarity index 100% rename from src/inc_internal/mesa_fuzzy.h rename to inc/mesa_fuzzy.h diff --git a/src/entry/Maat_api.cpp b/src/entry/Maat_api.cpp index 1822130..82e3bb5 100644 --- a/src/entry/Maat_api.cpp +++ b/src/entry/Maat_api.cpp @@ -1,6 +1,7 @@ #include #include #include + #include #include #include "rulescan.h" @@ -8,6 +9,7 @@ #include "Maat_rule.h" #include "Maat_rule_internal.h" #include "dynamic_array.h" +#include "aligment_int64.h" #include "config_monitor.h" #include "map_str2int.h" #include "rulescan.h" @@ -25,22 +27,29 @@ struct _Maat_table_info_t * acqurie_table(struct _Maat_feather_t* _feather,int t return NULL; } p_table=_feather->p_table_info[table_id]; - if(p_table==NULL||p_table->table_type!=expect_type) + if(p_table==NULL) { return NULL; } + if(p_table->table_type!=expect_type) + { + if(expect_type!=TABLE_TYPE_EXPR|| + p_table->table_type!=TABLE_TYPE_EXPR_PLUS) + { + return NULL; + } + } return p_table; } inline void INC_SCANNER_REF(_Maat_scanner_t*scanner,int thread_num) { - int offset=(CPU_CACHE_ALIGMENT/sizeof(int))*thread_num; - scanner->ref_cnt[offset]++; + aligment_int64_array_add(scanner->ref_cnt, thread_num, 1); return; } inline void DEC_SCANNER_REF(_Maat_scanner_t*scanner,int thread_num) { - int offset=(CPU_CACHE_ALIGMENT/sizeof(int))*thread_num; - scanner->ref_cnt[offset]--; + + aligment_int64_array_add(scanner->ref_cnt, thread_num, -1); return; } @@ -89,19 +98,18 @@ int pickup_hit_region_from_compile(universal_bool_expr_t *compile_hit,const unsi } return k; } -int region_compile(struct _scan_status_t *_mid,void* region_hit,int region_type_size,int group_offset,int region_hit_num,struct Maat_rule_t* result,_compile_result_t *rs_result, int size) +int region_compile(_Maat_feather_t*feather,struct _INNER_scan_status_t *_mid,void* region_hit,int region_type_size,int group_offset,int region_hit_num,struct Maat_rule_t* result,_compile_result_t *rs_result, int size,int thread_num) { int scan_ret=0,result_cnt=0; int ret=0,i=0,j=0; int r_in_c_cnt=0; - void* expr_compiler=_mid->feather->scanner->expr_compiler; int shortcut_avilable_cnt=0; + void* bool_matcher=feather->scanner->expr_compiler; struct _Maat_group_rule_t* group_rule=NULL; struct _Maat_compile_rule_t* array_mi_rule[MAX_SCANNER_HIT_NUM]; struct _Maat_compile_rule_t* _mi_rule=NULL; int region_pos[MAX_SCANNER_HIT_NUM]; - _mid->cur_hit_cnt=0; for(i=0;ithread_num, + scan_ret=boolexpr_match(bool_matcher,thread_num, _mid->hitted_group_id,_mid->hit_group_cnt, (void **)array_mi_rule, MAX_SCANNER_HIT_NUM); } @@ -157,16 +165,18 @@ int region_compile(struct _scan_status_t *_mid,void* region_hit,int region_type_ result_cnt++; } pthread_rwlock_unlock(&(_mi_rule->rwlock)); - - } - + } } + if(result_cnt>0) + { + aligment_int64_array_add(feather->hit_cnt,thread_num,1); + } return result_cnt; } -int exprid2region_id(struct _Maat_group_rule_t* group_rule,int expr_id) +int exprid2region_id(struct _Maat_group_rule_t* group_rule,int expr_id,int* district_id) { - int i=0,region_id=-1;; + int i=0,region_id=-1; struct _Maat_region_rule_t* region_rule=NULL; assert(group_rule->group_id>=0); pthread_mutex_lock(&(group_rule->mutex)); @@ -180,11 +190,34 @@ int exprid2region_id(struct _Maat_group_rule_t* group_rule,int expr_id) if(region_rule->expr_id==expr_id) { region_id=region_rule->region_id; + *district_id=region_rule->district_id; } } pthread_mutex_unlock(&(group_rule->mutex)); return region_id; } +int match_district(struct _OUTER_scan_status_t *_mid,scan_result_t *region_hit,int region_hit_num) +{ + struct _Maat_group_rule_t* group_rule=NULL; + int i=0; + int district_id=-1,region_id=-1; + int ret_region_num=region_hit_num; + while(i0&&district_id!=_mid->district_id) + { + ret_region_num--; + memmove(&(region_hit[i]),&(region_hit[i+1]),sizeof(scan_result_t)*(ret_region_num-i)); + } + else + { + i++; + } + } + return ret_region_num; +} int fill_regex_pos(struct regex_pos_t *regex_pos,int size,rule_result_t *rs_result,const char* buff) @@ -253,7 +286,7 @@ int hit_pos_RS2Maat(struct sub_item_pos_t* maat_sub_item,int size,rule_result_t* } return k; } -int fill_region_hit_detail(const char* scan_buff,const _scan_status_t* _mid, +int fill_region_hit_detail(const char* scan_buff,const _INNER_scan_status_t* _mid, scan_result_t *region_hit,int region_cnt, _compile_result_t *compile_hit,int compile_cnt, struct Maat_hit_detail_t *hit_detail,int detail_num) @@ -263,6 +296,7 @@ int fill_region_hit_detail(const char* scan_buff,const _scan_status_t* _mid, int region_pos[MAX_SCANNER_HIT_NUM],pos=0; int r_in_c_cnt=0; int region_id=-1; + int district_id=-1; //Indifferenc memset(r_in_c_flag,0,sizeof(r_in_c_flag)); memset(region_pos,0,sizeof(region_pos)); @@ -279,7 +313,7 @@ int fill_region_hit_detail(const char* scan_buff,const _scan_status_t* _mid, pos=region_pos[j]; r_in_c_flag[pos]=1; group_rule=(struct _Maat_group_rule_t*)(region_hit[pos].tag); - region_id=exprid2region_id(group_rule,region_hit[pos].expr_id); + region_id=exprid2region_id(group_rule,region_hit[pos].expr_id,&district_id); if(region_id<0) { continue; @@ -301,7 +335,7 @@ int fill_region_hit_detail(const char* scan_buff,const _scan_status_t* _mid, group_rule=(struct _Maat_group_rule_t*)(region_hit[k].tag); hit_detail[j].config_id=-2; hit_detail[j].hit_region_cnt=1; - hit_detail[j].region_pos[0].region_id=exprid2region_id(group_rule,region_hit[k].expr_id); + hit_detail[j].region_pos[0].region_id=exprid2region_id(group_rule,region_hit[k].expr_id,&district_id); hit_detail[j].region_pos[0].sub_item_num=region_hit[k].rnum; hit_pos_RS2Maat(hit_detail[j].region_pos[0].sub_item_pos,MAAT_MAX_EXPR_ITEM_NUM, region_hit[k].result,region_hit[k].rnum,scan_buff); @@ -310,19 +344,48 @@ int fill_region_hit_detail(const char* scan_buff,const _scan_status_t* _mid, } return j; } -struct _scan_status_t* _Maat_make_status(struct _Maat_feather_t* feather,int thread_num) +struct _INNER_scan_status_t* _make_inner_status(void) { - struct _scan_status_t* _mid=NULL; - _mid=(struct _scan_status_t*)calloc(sizeof(struct _scan_status_t),1); - _mid->feather=feather; - _mid->thread_num=thread_num; - _mid->cur_hit_cnt=0; - _mid->hit_group_cnt=0; - _mid->hit_group_size=4; - _mid->hitted_group_id=(unsigned int*)malloc(sizeof(unsigned int)*_mid->hit_group_size); + struct _INNER_scan_status_t* inner_mid=NULL; + inner_mid=(struct _INNER_scan_status_t*)calloc(sizeof(struct _INNER_scan_status_t),1); + inner_mid->cur_hit_cnt=0; + inner_mid->hit_group_cnt=0; + inner_mid->hit_group_size=4; + inner_mid->hitted_group_id=(unsigned int*)malloc(sizeof(unsigned int)*inner_mid->hit_group_size); + return inner_mid; +} +struct _OUTER_scan_status_t* _make_outer_status(_Maat_feather_t *feather,int thread_num) +{ + struct _OUTER_scan_status_t* outer_mid=NULL; + outer_mid=(struct _OUTER_scan_status_t*)calloc(sizeof(struct _OUTER_scan_status_t),1); + outer_mid->feather=feather; + outer_mid->district_id=-1; + outer_mid->thread_num=(unsigned short)thread_num; + aligment_int64_array_add(feather->outer_mid_cnt, thread_num,1); + return outer_mid; +} +struct _OUTER_scan_status_t* grab_mid(scan_status_t* raw_mid,_Maat_feather_t* feather,int thread_num,int is_hit_region) +{ + struct _OUTER_scan_status_t* _mid=NULL; + if(*raw_mid!=NULL) + { + _mid=(struct _OUTER_scan_status_t*)(*raw_mid); + } + if(is_hit_region==1) + { + if(_mid==NULL) + { + _mid=_make_outer_status(feather,thread_num); + *raw_mid=_mid; + } + if(_mid->inner==NULL) + { + _mid->inner=_make_inner_status(); + aligment_int64_array_add(feather->inner_mid_cnt,thread_num,1); + } + } return _mid; } - int detain_last_data(char* buff,int buff_size,int detained_len,const char* data,int data_len) { int to_copy_size=0,foward_offset=0; @@ -349,17 +412,10 @@ int detain_last_data(char* buff,int buff_size,int detained_len,const char* data, } return ret_len; } - - -Maat_feather_t Maat_summon_feather(int max_thread_num, - const char* table_info_path, - const char* ful_cfg_dir, - const char* inc_cfg_dir, - void* logger) +Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* logger) { - _Maat_feather_t* feather=(_Maat_feather_t*)calloc(sizeof(struct _Maat_feather_t),1); - feather->table_cnt=read_table_info(feather->p_table_info, MAX_TABLE_NUM,table_info_path,logger); + feather->table_cnt=read_table_info(feather->p_table_info, MAX_TABLE_NUM,table_info_path,max_thread_num,logger); feather->map_tablename2id=map_create(); int i=0; for(i=0;imap_tablename2id,feather->p_table_info[i]->table_name,feather->p_table_info[i]->table_id); } } - memcpy(feather->inc_dir,inc_cfg_dir,strlen(inc_cfg_dir)); - memcpy(feather->full_dir,ful_cfg_dir,strlen(ful_cfg_dir)); feather->logger=logger; feather->scan_thread_num=max_thread_num; feather->garbage_q=MESA_lqueue_create(0,0); - config_monitor_traverse(feather->maat_version, - ful_cfg_dir, - maat_start_cb, - maat_update_cb, - maat_finish_cb, - feather, - logger); - if(feather->update_tmp_scanner==NULL) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "At initiation: no valid index file in %s",ful_cfg_dir); - } - feather->scanner=feather->update_tmp_scanner; - feather->update_tmp_scanner=NULL; - feather->still_working=1; - if(feather->scanner!=NULL) - { - feather->maat_version=feather->scanner->version; - } feather->effect_interval_ms=60*1000; feather->scan_interval_ms=1*1000; - pthread_t cfg_mon_t; - pthread_create(&cfg_mon_t, NULL, thread_rule_monitor, (void*)feather); + feather->rule_scan_type=2; + feather->thread_call_cnt=aligment_int64_array_alloc(max_thread_num); + feather->outer_mid_cnt=aligment_int64_array_alloc(max_thread_num); + feather->inner_mid_cnt=aligment_int64_array_alloc(max_thread_num); + feather->hit_cnt=aligment_int64_array_alloc(max_thread_num); return feather; } -Maat_feather_t Maat_summon_feather_json(int max_thread_num, - const char* table_info_path, - const char* json_rule, - void* logger) -{ - Maat_feather_t feather; - char full_index_dir[256]={0}; - int ret=-1; - MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "Maat initial with JSON file %s.",json_rule); - - ret=json2iris(json_rule, full_index_dir,sizeof(full_index_dir),logger); - if(ret<0) - { - return NULL; - } - MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "generate index file %s OK.",full_index_dir); - feather=Maat_summon_feather(max_thread_num,table_info_path, full_index_dir, full_index_dir,logger); - return feather; -} -int Maat_set_feather_opt(Maat_feather_t feather,int type,void* value,int size) +int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const void* value,int size) { _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - int intval=0; + int intval=0,ret=-1; + if(_feather->still_working==1)// not allowed set after Maat_initiate_feather; + { + return -2; + } switch(type) { case MAAT_OPT_EFFECT_INVERVAL_MS: - intval=*(int*)value; + intval=*(const int*)value; if(size!=sizeof(int)||intval<=0) { return -1; @@ -439,18 +460,184 @@ int Maat_set_feather_opt(Maat_feather_t feather,int type,void* value,int size) _feather->effect_interval_ms=intval; break; case MAAT_OPT_SCANDIR_INTERVAL_MS: - intval=*(int*)value; + intval=*(const int*)value; if(size!=sizeof(int)||intval<0) { return -1; } _feather->scan_interval_ms=intval; break; + case MAAT_OPT_FULL_CFG_DIR: + if(size>(int)sizeof(_feather->full_dir)) + { + return -1; + } + memcpy(_feather->full_dir,(const char*)value,size); + break; + case MAAT_OPT_INC_CFG_DIR: + if(size>(int)sizeof(_feather->inc_dir)) + { + return -1; + } + memcpy(_feather->inc_dir,(const char*)value,size); + break; + case MAAT_OPT_JSON_FILE_PATH: + ret=json2iris((const char*)value, _feather->full_dir,sizeof(_feather->full_dir),_feather->logger); + if(ret<0) + { + return -1; + } + memcpy(_feather->inc_dir,_feather->full_dir,sizeof(_feather->inc_dir)); + MESA_handle_runtime_log(_feather->logger,RLOG_LV_INFO,maat_module , + "Maat initial with JSON file %s,generate index file %s OK." + ,(const char*)value + ,_feather->full_dir); + break; + case MAAT_OPT_STAT_ON: + _feather->stat_on=1; + _feather->stat_handle=FS_create_handle(); + break; + case MAAT_OPT_PERF_ON: + _feather->perf_on=1; + break; + case MAAT_OPT_STAT_FILE_PATH: + if(size>(int)sizeof(_feather->stat_file)) + { + return -1; + } + memcpy(_feather->stat_file,(const char*)value,size); + MESA_handle_runtime_log(_feather->logger,RLOG_LV_INFO,maat_module , + "Maat performance statistic output to %s." + ,(const char*)value); + _feather->stat_on=1; + break; + case MAAT_OPT_SCAN_DETAIL: + intval=*(const int*)value; + _feather->rule_scan_type=intval; + break; default: return -1; } return 0; } +int Maat_initiate_feather(Maat_feather_t feather) +{ + _Maat_feather_t* _feather=(_Maat_feather_t*)feather; + if(strlen(_feather->full_dir)==0) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: NO FULL_CFG_DIR or JSON_FILE_PATH. "); + + return -1; + } + config_monitor_traverse(_feather->maat_version, + _feather->full_dir, + maat_start_cb, + maat_update_cb, + maat_finish_cb, + _feather, + _feather->logger); + if(_feather->update_tmp_scanner==NULL) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: no valid index file in %s",_feather->full_dir); + } + _feather->scanner=_feather->update_tmp_scanner; + _feather->update_tmp_scanner=NULL; + _feather->still_working=1; + if(_feather->scanner!=NULL) + { + _feather->maat_version=_feather->scanner->version; + } + if(strlen(_feather->stat_file)==0) + { + if(_feather->stat_on==1) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: MAAT_OPT_STAT_FILE_PATH not set,TURN OFF STAT trigger."); + } + _feather->stat_on=0; + } + if(_feather->stat_on==0&&_feather->perf_on==1) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: STAT tirigger OFF, TURN OFF PERF trigger."); + _feather->perf_on=0; + } + maat_stat_init(_feather); + + pthread_t cfg_mon_t; + pthread_create(&cfg_mon_t, NULL, thread_rule_monitor, (void*)_feather); + return 0; + +} + +Maat_feather_t Maat_summon_feather(int max_thread_num, + const char* table_info_path, + const char* ful_cfg_dir, + const char* inc_cfg_dir, + void* logger) +{ + int ret=-1; + Maat_feather_t feather=NULL; + feather=Maat_feather(max_thread_num,table_info_path,logger); + if(feather==NULL) + { + return NULL; + } + ret=Maat_set_feather_opt(feather, MAAT_OPT_FULL_CFG_DIR, ful_cfg_dir, strlen(ful_cfg_dir)+1); + if(ret<0) + { + goto error_out; + } + ret=Maat_set_feather_opt(feather, MAAT_OPT_INC_CFG_DIR, inc_cfg_dir, strlen(inc_cfg_dir)+1); + if(ret<0) + { + goto error_out; + } + ret=Maat_initiate_feather(feather); + if(ret<0) + { + goto error_out; + } + return feather; + +error_out: + Maat_burn_feather(feather); + return NULL; + + +} +Maat_feather_t Maat_summon_feather_json(int max_thread_num, + const char* table_info_path, + const char* json_rule, + void* logger) +{ + int ret=-1; + Maat_feather_t feather=NULL; + feather=Maat_feather(max_thread_num,table_info_path,logger); + if(feather==NULL) + { + return NULL; + } + ret=Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, json_rule, strlen(json_rule)+1); + if(ret<0) + { + goto error_out; + } + ret=Maat_initiate_feather(feather); + if(ret<0) + { + goto error_out; + } return feather; + +error_out: + + Maat_burn_feather(feather); + return NULL; + +} + void Maat_burn_feather(Maat_feather_t feather) { _Maat_feather_t* _feather=(_Maat_feather_t*)feather; @@ -503,7 +690,10 @@ int Maat_table_callback_register(Maat_feather_t feather,short table_id, p_table->cb_info->cb_plug[idx].u_para=u_para; if(p_table->cb_info->line_num>0) { - start(MAAT_RULE_UPDATE_TYPE_FULL,u_para); + if(start!=NULL) + { + start(MAAT_RULE_UPDATE_TYPE_FULL,u_para); + } for(i=0;icb_info->line_num;i++) { lines=(const char*)dynamic_array_read(p_table->cb_info->cache_lines,i); @@ -513,7 +703,10 @@ int Maat_table_callback_register(Maat_feather_t feather,short table_id, } update(table_id,lines,u_para); } - finish(u_para); + if(finish!=NULL) + { + finish(u_para); + } } pthread_mutex_unlock(&(p_table->cb_info->plugin_mutex)); return 1; @@ -526,12 +719,21 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id int region_ret=0,compile_ret=0,hit_region_cnt=0; unsigned int sub_type=0; struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct _scan_status_t* _mid=NULL; + struct _OUTER_scan_status_t* _mid=(struct _OUTER_scan_status_t*)(*mid); scan_result_t *region_result=NULL; _compile_result_t compile_result[rule_num];//dynamic array - struct _Maat_table_info_t *p_table=NULL; + struct timespec start,end; + if(data==NULL||data_len<=0) + { + return 0; + } + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&start); + } + _mid=grab_mid(mid,_feather, thread_num, 0); p_table=acqurie_table(_feather, table_id,TABLE_TYPE_EXPR); if(p_table==NULL) { @@ -541,6 +743,10 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id { return 0; } + if(p_table->table_type==TABLE_TYPE_EXPR_PLUS&&(_mid==NULL||_mid->is_set_district!=1)) + { + return -1; + } if(p_table->do_charset_merge==1) { sub_type=make_sub_type(table_id,CHARSET_NONE,0); @@ -549,7 +755,7 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id { sub_type=make_sub_type(table_id,charset,0); } - + aligment_int64_array_add(_feather->thread_call_cnt, thread_num, 1); scan_data_t scan_data; scan_data.text_data.text=data; scan_data.text_data.tlen=data_len; @@ -585,30 +791,38 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id } } + if(hit_region_cnt>0&&p_table->table_type==TABLE_TYPE_EXPR_PLUS) + { + hit_region_cnt=match_district(_mid,region_result,hit_region_cnt); + } if(hit_region_cnt>0) { - if(*mid==NULL) - { - _mid=_Maat_make_status(_feather,thread_num); - *mid=_mid; - } - else - { - _mid=(struct _scan_status_t*)(*mid); - } - compile_ret=region_compile(_mid, + aligment_int64_array_add(p_table->hit_cnt, thread_num,1); + _mid=grab_mid(mid,_feather,thread_num, 1); + compile_ret=region_compile(_feather,_mid->inner, region_result,sizeof(scan_result_t),offsetof(scan_result_t, tag), hit_region_cnt, - result,compile_result,rule_num); - if(hit_detail!=NULL) + result,compile_result,rule_num, + thread_num); + if(hit_detail!=NULL&&_feather->rule_scan_type!=0) { - *detail_ret=fill_region_hit_detail(data,_mid, + *detail_ret=fill_region_hit_detail(data,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, hit_detail,detail_num); } } DEC_SCANNER_REF(my_scanner, thread_num); + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&end); + maat_stat_table(p_table,data_len,&start, &end,thread_num); + } + else + { + maat_stat_table(p_table,data_len,NULL, NULL,thread_num); + } + if(compile_ret==0&&hit_region_cnt>0) { return -2; @@ -633,7 +847,7 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id ,scan_status_t *mid,int thread_num) { int region_ret=0,compile_ret=0; - struct _scan_status_t* _mid=NULL; + struct _OUTER_scan_status_t* _mid=NULL; scan_data_t intval_scan_data; scan_result_t *region_result=NULL; _compile_result_t compile_result[rule_num]; @@ -643,6 +857,11 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id intval_scan_data.sub_type=make_sub_type(table_id,CHARSET_NONE, 0); intval_scan_data.int_data=intval; _Maat_table_info_t* p_table=NULL; + struct timespec start,end; + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&start); + } p_table=acqurie_table(_feather,table_id,TABLE_TYPE_INTVAL); if(p_table==NULL) { @@ -657,6 +876,7 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id { return 0; } + aligment_int64_array_add(_feather->thread_call_cnt, thread_num, 1); region_result=my_scanner->region_rslt_buff+MAX_SCANNER_HIT_NUM*thread_num; @@ -669,22 +889,25 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id } else if(region_ret>0) { - if(*mid==NULL) - { - _mid=_Maat_make_status(_feather,thread_num); - *mid=_mid; - } - else - { - _mid=(struct _scan_status_t*)(*mid); - } - compile_ret=region_compile(_mid, + aligment_int64_array_add(p_table->hit_cnt, thread_num,1); + _mid=grab_mid(mid, _feather, thread_num, 1); + compile_ret=region_compile(_feather,_mid->inner, region_result,sizeof(scan_result_t),offsetof(scan_result_t, tag), region_ret, - result,compile_result,rule_num); + result,compile_result,rule_num, + thread_num); } DEC_SCANNER_REF(my_scanner,thread_num); + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&end); + maat_stat_table(p_table,0,&start, &end,thread_num); + } + else + { + maat_stat_table(p_table,0,NULL, NULL,thread_num); + } if(compile_ret==0&®ion_ret>0) { return -2; @@ -699,7 +922,7 @@ int Maat_scan_proto_addr(Maat_feather_t feather,int table_id ,scan_status_t *mid,int thread_num) { int region_ret=0,compile_ret=0; - struct _scan_status_t* _mid=NULL; + struct _OUTER_scan_status_t* _mid=NULL; scan_data_t ip_scan_data; scan_result_t *region_result=NULL; _compile_result_t compile_result[rule_num]; @@ -707,6 +930,11 @@ int Maat_scan_proto_addr(Maat_feather_t feather,int table_id struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; struct _Maat_scanner_t* my_scanner=NULL; + struct timespec start,end; + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&start); + } p_table=acqurie_table(_feather, table_id, TABLE_TYPE_IP); if(p_table==NULL) { @@ -716,11 +944,21 @@ int Maat_scan_proto_addr(Maat_feather_t feather,int table_id { return 0; } + if(p_table->ipv4_rule_cnt==0&&addr->addrtype==ADDR_TYPE_IPV4) + { + return 0; + } + if(p_table->ipv6_rule_cnt==0&&addr->addrtype==ADDR_TYPE_IPV6) + { + return 0; + } my_scanner=_feather->scanner; if(my_scanner==NULL) { return 0; } + aligment_int64_array_add(_feather->thread_call_cnt, thread_num, 1); + ip_scan_data.rule_type=RULETYPE_IPv4; ip_scan_data.sub_type=make_sub_type(table_id,CHARSET_NONE, 0); switch(addr->addrtype) @@ -758,22 +996,24 @@ int Maat_scan_proto_addr(Maat_feather_t feather,int table_id } else if(region_ret>0) { - if(*mid==NULL) - { - _mid=_Maat_make_status(_feather,thread_num); - *mid=_mid; - } - else - { - _mid=(struct _scan_status_t*)(*mid); - } - compile_ret=region_compile(_mid, + aligment_int64_array_add(p_table->hit_cnt, thread_num,1); + _mid=grab_mid(mid, _feather, thread_num, 1); + compile_ret=region_compile(_feather,_mid->inner, region_result,sizeof(scan_result_t),offsetof(scan_result_t, tag), region_ret, - result,compile_result,rule_num); + result,compile_result,rule_num, + thread_num); } DEC_SCANNER_REF(my_scanner,thread_num); - + if(_feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&end); + maat_stat_table(p_table,0,&start, &end,thread_num); + } + else + { + maat_stat_table(p_table,0,NULL, NULL,thread_num); + } if(compile_ret==0&®ion_ret>0) { return -2; @@ -834,6 +1074,7 @@ stream_para_t Maat_stream_scan_string_start(Maat_feather_t feather,int table_id, { sp->do_regex=1; } + aligment_int64_array_add(p_table->stream_num,thread_num,1); sp->rs_stream_para=rulescan_startstream(_feather->scanner->region,thread_num); return sp; } @@ -848,14 +1089,22 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para int sub_type=0; int region_ret=0,hit_region_cnt=0,compile_ret=0; - struct _scan_status_t* _mid=(struct _scan_status_t*)(*mid); + struct _OUTER_scan_status_t* _mid=NULL; scan_result_t *region_result; _compile_result_t compile_result[rule_num];//dynamic array scan_data_t region_scan_data; - if(data==NULL||data_len==0) + _Maat_table_info_t* p_table=NULL; + struct timespec start,end; + if(data==NULL||data_len<=0) { return 0; } + if(sp->feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&start); + } + _mid=grab_mid(mid, sp->feather, sp->thread_num,0); + if(scanner==NULL) { return 0; @@ -864,10 +1113,17 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para { return 0; } - if(sp->feather->p_table_info[sp->table_id]->cfg_num==0) + p_table=sp->feather->p_table_info[sp->table_id]; + if(p_table->cfg_num==0) { return 0; } + if(p_table->table_type==TABLE_TYPE_EXPR_PLUS&&(_mid==NULL||_mid->is_set_district!=1)) + { + return -1; + } + aligment_int64_array_add(sp->feather->thread_call_cnt, sp->thread_num, 1); + region_result=scanner->region_rslt_buff+MAX_SCANNER_HIT_NUM*sp->thread_num; *detail_ret=0; if(sp->do_merge==1) @@ -937,33 +1193,31 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para hit_region_cnt+=region_ret; } } + if(hit_region_cnt>0&&p_table->table_type==TABLE_TYPE_EXPR_PLUS) + { + hit_region_cnt=match_district(_mid,region_result,hit_region_cnt); + } if(hit_region_cnt>0) { - if(*mid==NULL) - { - _mid=_Maat_make_status(sp->feather,sp->thread_num); - *mid=_mid; - } - else - { - _mid=(struct _scan_status_t*)(*mid); - } - compile_ret=region_compile(_mid, + aligment_int64_array_add(p_table->hit_cnt, sp->thread_num,1); + _mid=grab_mid(mid, sp->feather,sp->thread_num, 1); + compile_ret=region_compile(sp->feather,_mid->inner, region_result,sizeof(scan_result_t),offsetof(scan_result_t, tag), hit_region_cnt, - result,compile_result,rule_num); - if(hit_detail!=NULL) + result,compile_result,rule_num, + sp->thread_num); + if(hit_detail!=NULL&&sp->feather->rule_scan_type!=0) { if(sp->scan_buff!=NULL) { - *detail_ret=fill_region_hit_detail(sp->scan_buff,_mid, + *detail_ret=fill_region_hit_detail(sp->scan_buff,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, hit_detail,detail_num); } else { - *detail_ret=fill_region_hit_detail(data,_mid, + *detail_ret=fill_region_hit_detail(data,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, hit_detail,detail_num); @@ -973,7 +1227,16 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para if(*detail_ret==0) { free(sp->scan_buff); - sp->scan_buff=0; + sp->scan_buff=NULL; + } + if(sp->feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&end); + maat_stat_table(sp->feather->p_table_info[sp->table_id],data_len,&start, &end,sp->thread_num); + } + else + { + maat_stat_table(sp->feather->p_table_info[sp->table_id],data_len,NULL, NULL,sp->thread_num); } if(compile_ret==0&&hit_region_cnt>0) { @@ -998,7 +1261,8 @@ void Maat_stream_scan_string_end(stream_para_t* stream_para) { struct _stream_para_t* sp=(struct _stream_para_t*)(*stream_para); struct _Maat_scanner_t* scanner=sp->feather->scanner; - + struct _Maat_table_info_t * p_table=sp->feather->p_table_info[sp->table_id]; + aligment_int64_array_add(p_table->stream_num,sp->thread_num,-1); if(scanner!=NULL) { if(sp->version==sp->feather->maat_version) @@ -1056,6 +1320,7 @@ stream_para_t Maat_stream_scan_digest_start(Maat_feather_t feather,int table_id, sp->total_len=total_len; sp->fuzzy_hash_handle=tmp_fuzzy_handle; pthread_mutex_init(&(sp->fuzzy_mutex),NULL); + aligment_int64_array_add(p_table->stream_num,thread_num,1); return sp; } @@ -1069,7 +1334,7 @@ inline int REACH_QUERY_THRESH(unsigned long long total_len,unsigned long long ac // { // return 1; // } - if(rate<(unsigned long long)(point_size+QUERY_MIN_RATE)) + if(rate>(unsigned long long)(point_size+QUERY_MIN_RATE)) { return 0; } @@ -1087,15 +1352,29 @@ int Maat_stream_scan_digest(stream_para_t * stream_para, const char * data, int GIE_result_t query_result[MAX_SCANNER_HIT_NUM]; int hit_region_cnt=0,compile_ret=0; _compile_result_t compile_result[rule_num];//dynamic array + if(data==NULL||data_len<=0) + { + return 0; + } + if(sp->feather->scanner==NULL) + { + return 0; + } GIE_handle_t* GIE_handle=sp->feather->scanner->digest_handle[sp->table_id]; unsigned long long digest_len=0; char* digest_buff=NULL; - struct _scan_status_t* _mid=(struct _scan_status_t*)(*mid); + struct _OUTER_scan_status_t* _mid=NULL; pthread_rwlock_t *GIE_rwlock=&(sp->feather->scanner->digest_rwlock[sp->table_id]); + struct timespec start,end; + if(sp->feather->perf_on==1) + { + clock_gettime(CLOCK_MONOTONIC,&start); + } if(sp->acc_scan_len+(unsigned long long)data_len > sp->total_len) { return 0; } + aligment_int64_array_add(sp->feather->thread_call_cnt, sp->thread_num, 1); pthread_mutex_lock(&(sp->fuzzy_mutex)); sp->acc_scan_len+=fuzzy_feed(sp->fuzzy_hash_handle, data, (unsigned int)data_len,offset); pthread_mutex_unlock(&(sp->fuzzy_mutex)); @@ -1129,24 +1408,26 @@ int Maat_stream_scan_digest(stream_para_t * stream_para, const char * data, int { return -1; } - if(hit_region_cnt==0) + if(hit_region_cnt>0) { - return 0; + sp->feather->p_table_info[sp->table_id]->hit_cnt++; + _mid=grab_mid(mid,sp->feather, sp->thread_num,1); + compile_ret=region_compile(sp->feather,_mid->inner, + query_result,sizeof(GIE_result_t),offsetof(GIE_result_t, tag), + hit_region_cnt, + result,compile_result,rule_num, + sp->thread_num); + } - - if(*mid==NULL) + if(sp->feather->perf_on==1) { - _mid=_Maat_make_status(sp->feather,sp->thread_num); - *mid=_mid; + clock_gettime(CLOCK_MONOTONIC,&end); + maat_stat_table(sp->feather->p_table_info[sp->table_id],data_len,&start, &end,sp->thread_num); } else { - _mid=(struct _scan_status_t*)(*mid); + maat_stat_table(sp->feather->p_table_info[sp->table_id],data_len,NULL, NULL,sp->thread_num); } - compile_ret=region_compile(_mid, - query_result,sizeof(GIE_result_t),offsetof(GIE_result_t, tag), - hit_region_cnt, - result,compile_result,rule_num); if(compile_ret==0&&hit_region_cnt>0) { return -2; @@ -1157,7 +1438,8 @@ void Maat_stream_scan_digest_end(stream_para_t* stream_para) { struct _stream_para_t* sp=(struct _stream_para_t*)(*stream_para); struct _Maat_scanner_t* scanner=sp->feather->scanner; - + struct _Maat_table_info_t * p_table=sp->feather->p_table_info[sp->table_id]; + aligment_int64_array_add(p_table->stream_num,sp->thread_num,-1); if(scanner!=NULL) { if(sp->version==sp->feather->maat_version) @@ -1171,18 +1453,54 @@ void Maat_stream_scan_digest_end(stream_para_t* stream_para) assert(sp->scan_buff==NULL); free(sp); *stream_para=NULL; + return; } +int Maat_set_scan_status(Maat_feather_t feather,scan_status_t* mid,enum MAAT_SCAN_OPT type,const void* value,int size) +{ + struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; + struct _OUTER_scan_status_t* _mid=NULL; + int map_ret=-1; + _mid=grab_mid(mid,_feather, 0, 0); + if(_mid==NULL) + { + _mid=_make_outer_status(_feather,0); + *mid=_mid; + } + switch(type) + { + case MAAT_SET_SCAN_DISTRICT: + map_ret=map_str2int(_feather->scanner->district_map,(const char*)value,&(_mid->district_id)); + if(map_ret<0) + { + //May be the district is not effected yet. + } + _mid->is_set_district=1; + break; + default: + return -1; + break; + } + return 0; +} void Maat_clean_status(scan_status_t* mid) { - struct _scan_status_t* _mid=NULL; + struct _OUTER_scan_status_t* _mid=NULL; if(*mid==NULL) { return; } - _mid=(struct _scan_status_t*)(*mid); - free(_mid->hitted_group_id); + _mid=(struct _OUTER_scan_status_t*)(*mid); + aligment_int64_array_add(_mid->feather->outer_mid_cnt,_mid->thread_num,-1); + if(_mid->inner!=NULL) + { + free(_mid->inner->hitted_group_id); + free(_mid->inner); + aligment_int64_array_add(_mid->feather->inner_mid_cnt,_mid->thread_num,-1); + } + _mid->feather=NULL; free(_mid); *mid=NULL; return; } + diff --git a/src/entry/Maat_rule.cpp b/src/entry/Maat_rule.cpp index 08237de..65c5375 100644 --- a/src/entry/Maat_rule.cpp +++ b/src/entry/Maat_rule.cpp @@ -11,11 +11,13 @@ #include #include #include +#include #include "Maat_rule.h" #include "Maat_rule_internal.h" #include "json2iris.h" #include "dynamic_array.h" +#include "aligment_int64.h" #include "config_monitor.h" #include "map_str2int.h" @@ -24,11 +26,11 @@ #include "mesa_fuzzy.h" #include "great_index_engine.h" -int MAAT_FRAME_VERSION_1_3_20160131=1; +int MAAT_FRAME_VERSION_1_8_20160603=1; const char *maat_module="MAAT Frame"; -const char* CHARSET_STRING[]={"CHARSET_NONE","GBK","BIG5","UNICODE","UTF-8"}; - +const char* CHARSET_STRING[]={"NONE","gbk","big5","unicode","utf8","bin", + "unicode_ascii_esc","unicode_ascii_aligned","unicode_ncr_dec","unicode_ncr_hex","url_encode_gb2312","url_encode_utf8",""}; int converHextoint(char srctmp) { if(isdigit(srctmp)) @@ -78,6 +80,7 @@ iconv_t maat_iconv_open(struct _Maat_scanner_t* scanner,enum MAAT_CHARSET to,enu cd=scanner->iconv_handle[to][from]; return cd; } + int iconv_convert(struct _Maat_scanner_t* scanner,enum MAAT_CHARSET from,enum MAAT_CHARSET to,char *src,int srclen,char *dst,int *dstlen) { size_t ret; @@ -103,7 +106,8 @@ int iconv_convert(struct _Maat_scanner_t* scanner,enum MAAT_CHARSET from,enum MA if(ret!=(size_t)(-1)) { - if(to==CHARSET_UNICODE)//jump unicode 2 bytes head 0xFF 0xFE + if(to==CHARSET_UNICODE&& + (*(unsigned short*)pOutBuff==0xFFFE||*(unsigned short*)pOutBuff==0XFEFF))//jump unicode 2 bytes BOM, 0xFF 0xFE { copy_len=iOutBuffLen-iLeftLen-2; copy_buf=pOutBuff+2; @@ -132,7 +136,137 @@ int iconv_convert(struct _Maat_scanner_t* scanner,enum MAAT_CHARSET from,enum MA } } +int URLEncode(const char* str, const int strSize, char* result, const int resultSize) +{ + int i; + int j = 0;//for result index + char ch; + if ((str==NULL) || (result==NULL) || (strSize<=0) || (resultSize<=0)) + { + return -1; + } + + for ( i=0; (i='A') && (ch<'Z')) || + ((ch>='a') && (ch<'z')) || + ((ch>='0') && (ch<'9'))) + { + result[j++] = ch; + } + else if (ch == ' ') + { + result[j++] = '+'; + } + else if (ch == '.' || ch == '-' || ch == '_' || ch == '*') + { + result[j++] = ch; + } + else + { + if (j+3 < resultSize) + { + sprintf(result+j, "%%%02X", (unsigned char)ch); + j += 3; + } + else + { + return -1; + } + } + } + + result[j] = '\0'; + return j; +} +int uni2ascii(const char* fmt,const char* src, const int srclen, char* dst, const int dstsize) +{ + int i=0,j=0; + assert(srclen%2==0);//unicode must be 2 bytes aligned. + while(iscan_cnt=aligment_int64_array_alloc(max_thread_num); + p->scan_cpu_time=aligment_int64_array_alloc(max_thread_num); + p->input_bytes=aligment_int64_array_alloc(max_thread_num); + p->stream_num=aligment_int64_array_alloc(max_thread_num); + p->hit_cnt=aligment_int64_array_alloc(max_thread_num); + p->cross_cache_size=0; + return p; +} +void destroy_table_info(struct _Maat_table_info_t*p) +{ + aligment_int64_array_free(p->scan_cnt); + aligment_int64_array_free(p->scan_cpu_time); + aligment_int64_array_free(p->input_bytes); + aligment_int64_array_free(p->stream_num); + aligment_int64_array_free(p->hit_cnt); + free(p); + return; +} +int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_info_path,int max_thread_num,void* logger) { FILE*fp=NULL; char line[MAX_TABLE_LINE_SIZE]; int i=0,j=0,ret[4]={0},table_cnt=0; - char table_type[16],src_charset[16],dst_charset[64],merge[4]; + char table_type[16],src_charset[256],dst_charset[256],merge[4]; MESA_htable_handle string2int_map=map_create(); char *token=NULL,*sub_token=NULL,*saveptr; struct _Maat_table_info_t*p=NULL; @@ -269,12 +415,28 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* map_register(string2int_map,"plugin", TABLE_TYPE_PLUGIN); map_register(string2int_map,"intval", TABLE_TYPE_INTVAL); map_register(string2int_map,"digest", TABLE_TYPE_DIGEST); + map_register(string2int_map,"expr_plus", TABLE_TYPE_EXPR_PLUS); map_register(string2int_map,"group", TABLE_TYPE_GROUP); - map_register(string2int_map,"bin", CHARSET_NONE); + for(i=0;i0) + { + map_register(string2int_map,CHARSET_STRING[i], i); + } + else + { + break; + } + } + +/* map_register(string2int_map,"gbk", CHARSET_GBK); map_register(string2int_map,"big5", CHARSET_BIG5); map_register(string2int_map,"unicode", CHARSET_UNICODE); map_register(string2int_map,"utf8", CHARSET_UTF8); + map_register(string2int_map,"unicode_hex", CHARSET_UNICODE_ASCII_ESC); + map_register(string2int_map,"unicode_hex", CHARSET_UNICODE_ASCII_ESC); +*/ map_register(string2int_map,"yes", 1); map_register(string2int_map,"no", 0); @@ -285,6 +447,7 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s error.\n",table_info_path); } + i=0; while(NULL!=fgets(line,sizeof(line),fp)) { i++; @@ -293,8 +456,8 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* { continue; } - p=(struct _Maat_table_info_t*)calloc(sizeof(struct _Maat_table_info_t),1); - p->cross_cache_size=0; + p=create_table_info(max_thread_num); + sscanf(line,"%hu\t%s\t%s\t%s\t%s\t%s\t%d",&(p->table_id) ,p->table_name ,table_type @@ -309,9 +472,9 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* { if(ret[j]<0) { - fprintf(stderr,"Maat read table info %s line %d error.\n",table_info_path,i); + fprintf(stderr,"Maat read table info %s line %d error:unknown column.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, - "Maat read table info %s line %d error.\n",table_info_path,i); + "Maat read table info %s line %d error:unknown column.\n",table_info_path,i); goto error_jump; } } @@ -332,9 +495,9 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* } else { - fprintf(stderr,"Maat read table info %s line %d error.\n",table_info_path,i); + fprintf(stderr,"Maat read table info %s line %d error:unknown dest charset %s.\n",table_info_path,i,sub_token); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, - "Maat read table info %s line %d error.\n",table_info_path,i); + "Maat read table info %s line %d error: unknown dest charset %s.\n",table_info_path,i,sub_token); goto error_jump; } @@ -365,7 +528,7 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_cnt++; continue; error_jump: - free(p); + destroy_table_info(p); p=NULL; } fclose(fp); @@ -601,6 +764,7 @@ struct op_expr_t* create_op_expr(unsigned int expr_id,int operation,void* u_para { struct op_expr_t* op_expr=NULL; op_expr=(struct op_expr_t*)calloc(sizeof(struct op_expr_t),1); + op_expr->no_effect_convert_cnt=0; op_expr->p_expr=(boolean_expr_t*)calloc(sizeof(boolean_expr_t),1); op_expr->p_expr->expr_id=expr_id; op_expr->p_expr->operation=operation; @@ -673,7 +837,7 @@ void destroy_digest_rule(GIE_digest_t*rule) rule=NULL; return; } -struct _Maat_scanner_t* create_maat_scanner(unsigned int version,int scan_thread_num,MESA_lqueue_head tomb) +struct _Maat_scanner_t* create_maat_scanner(unsigned int version,int scan_thread_num,MESA_lqueue_head tomb,int rs_scan_type) { int i=0; @@ -682,7 +846,7 @@ struct _Maat_scanner_t* create_maat_scanner(unsigned int version,int scan_thread hargs.thread_safe=0; hargs.hash_slot_size = 1024*1024; hargs.max_elem_num = 0; - hargs.eliminate_type = HASH_ELIMINATE_ALGO_LRU; + hargs.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; hargs.expire_time = 0; hargs.key_comp = NULL; hargs.key2index = NULL; @@ -706,14 +870,17 @@ struct _Maat_scanner_t* create_maat_scanner(unsigned int version,int scan_thread scanner->region_hash=MESA_htable_create(&hargs, sizeof(hargs)); MESA_htable_print_crtl(scanner->region_hash,0); + + scanner->district_map=map_create(); scanner->version=version; scanner->cfg_num=0; scanner->max_thread_num=scan_thread_num; //optimized for CPU cache_alignment 64 - scanner->ref_cnt=(int*)calloc(CPU_CACHE_ALIGMENT,scan_thread_num); + scanner->ref_cnt=aligment_int64_array_alloc(scan_thread_num); scanner->region_update_q=MESA_lqueue_create(0,0); scanner->region=rulescan_initialize(scan_thread_num); + rulescan_set_param(scanner->region,rs_scan_type); scanner->tomb_ref=tomb; scanner->region_rslt_buff=(scan_result_t*)malloc(sizeof(scan_result_t)*MAX_SCANNER_HIT_NUM*scan_thread_num); @@ -737,7 +904,7 @@ void destroy_maat_scanner(struct _Maat_scanner_t*scanner) MESA_htable_destroy(scanner->compile_hash,NULL); MESA_htable_destroy(scanner->group_hash, NULL); MESA_htable_destroy(scanner->region_hash, NULL); - + map_destroy(scanner->district_map); destroy_bool_matcher((void*)scanner->expr_compiler); q_cnt=MESA_lqueue_get_count(scanner->region_update_q); for(i=0;ilast_update_time=time(NULL); return; } -struct _Maat_group_rule_t* add_region_to_group(struct _Maat_group_rule_t* group,int region_id,int expr_id,enum MAAT_TABLE_TYPE region_type) +struct _Maat_group_rule_t* add_region_to_group(struct _Maat_group_rule_t* group,int region_id,int district_id,int expr_id,enum MAAT_TABLE_TYPE region_type) { struct _Maat_region_rule_t* region_rule=(struct _Maat_region_rule_t*)malloc(sizeof(struct _Maat_region_rule_t)); region_rule->region_id=region_id; region_rule->expr_id=expr_id; + region_rule->district_id=district_id; region_rule->region_type=region_type; pthread_mutex_lock(&(group->mutex)); dynamic_array_write(group->region_rules,group->region_boundary,region_rule); @@ -1075,12 +1243,24 @@ int sync_region(MESA_htable_handle region_hash,int region_id,const char* table_n } return 1; } +int get_district_id(_Maat_scanner_t *scanner,const char* district_str) +{ + int map_ret=0,district_id=-1; + map_ret=map_str2int(scanner->district_map, district_str,&district_id); + if(map_ret<0) + { + district_id= scanner->district_num; + map_register(scanner->district_map,district_str, district_id); + scanner->district_num++; + } + return district_id; +} int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule,struct _Maat_scanner_t *scanner,void* logger) { unsigned int i=0,j=0; char* p=NULL,*saveptr=NULL,*region_string=NULL; int region_str_len=0,ret=0,k=0; - int expr_id=0; + int expr_id=0,district_id=-1; scan_rule_t*p_rule=NULL; struct _Maat_group_rule_t* group_rule=NULL; @@ -1095,7 +1275,12 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule int sub_expr_cnt=0; struct op_expr_t *op_expr=NULL; struct _Maat_group_rule_t* u_para=NULL; - + + if(table->table_type==TABLE_TYPE_EXPR_PLUS) + { + assert(strlen(db_rule->district)>0); + district_id=get_district_id(scanner, db_rule->district); + } group_rule=(struct _Maat_group_rule_t*)HASH_fetch_by_id(scanner->group_hash, db_rule->group_id); if(group_rule==NULL) { @@ -1167,7 +1352,7 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule break; case EXPR_TYPE_REGEX://it's easy,no need to charset convert expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,db_rule->region_id,expr_id,TABLE_TYPE_EXPR); + u_para=add_region_to_group(group_rule,db_rule->region_id,district_id,expr_id,TABLE_TYPE_EXPR); if(u_para==NULL) { return -1; @@ -1233,7 +1418,7 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule break; } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule, db_rule->region_id,expr_id, TABLE_TYPE_EXPR); + u_para=add_region_to_group(group_rule, db_rule->region_id,district_id,expr_id, table->table_type); if(u_para==NULL)//duplicate { return -1; @@ -1248,12 +1433,12 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule { continue; } - region_str_len=strlen(sub_key_array[k])*2+1; + region_str_len=strlen(sub_key_array[k])*8+1; // 1 byte map to 8 bytes maximum, e.g. "ا" or "\u63221;" region_string=(char*)calloc(sizeof(char),region_str_len); if(table->src_charset!=dst_charset)//need convert { - ret=iconv_convert(scanner,table->src_charset, dst_charset, + ret=universal_charset_convert(scanner,table->src_charset, dst_charset, sub_key_array[k],strlen(sub_key_array[k]), region_string, ®ion_str_len); if(ret<0) @@ -1266,13 +1451,10 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule free(region_string); continue; } - //if convert take no effect if(region_str_len==(int)strlen(sub_key_array[k])&& - 0==memcmp(sub_key_array[k],region_string,region_str_len)&& - TRUE==table->src_charset_in_dst) + 0==memcmp(sub_key_array[k],region_string,region_str_len)) { - free(region_string); - continue; + op_expr->no_effect_convert_cnt++;; } } else @@ -1291,14 +1473,23 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule free(region_string); region_string=NULL; } - MESA_lqueue_join_tail(scanner->region_update_q,&op_expr, sizeof(void*)); + //if each sub string's convert take no effect and src charset is one of the dst. + if(TRUE==table->src_charset_in_dst&&op_expr->no_effect_convert_cnt==sub_expr_cnt) + { + destroy_op_expr(op_expr); + op_expr=NULL; + } + else + { + MESA_lqueue_join_tail(scanner->region_update_q,&op_expr, sizeof(void*)); + } } } else { expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule, db_rule->region_id,expr_id, TABLE_TYPE_EXPR); + u_para=add_region_to_group(group_rule, db_rule->region_id,district_id,expr_id, table->table_type); if(u_para==NULL) { return -1; @@ -1334,7 +1525,7 @@ int add_ip_rule(struct _Maat_table_info_t* table,struct db_ip_rule_t* db_ip_rule scan_rule_t* p_rule=NULL; struct op_expr_t* op_expr=NULL; struct _Maat_group_rule_t* u_para=NULL; - int expr_id=0; + int expr_id=0,district_id=-1; group_rule=(struct _Maat_group_rule_t*)HASH_fetch_by_id(scanner->group_hash, db_ip_rule->group_id); if(group_rule==NULL) @@ -1344,7 +1535,7 @@ int add_ip_rule(struct _Maat_table_info_t* table,struct db_ip_rule_t* db_ip_rule } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,db_ip_rule->region_id,expr_id,TABLE_TYPE_IP); + u_para=add_region_to_group(group_rule,db_ip_rule->region_id,district_id,expr_id,TABLE_TYPE_IP); if(u_para==NULL) { return -1; @@ -1365,8 +1556,8 @@ int add_intval_rule(struct _Maat_table_info_t* table,struct db_intval_rule_t* in scan_rule_t* p_rule=NULL; struct op_expr_t* op_expr=NULL; struct _Maat_group_rule_t* u_para=NULL; - int expr_id=0; - + int expr_id=0,district_id=-1; + group_rule=(struct _Maat_group_rule_t*)HASH_fetch_by_id(scanner->group_hash, intval_rule->group_id); if(group_rule==NULL) { @@ -1374,7 +1565,7 @@ int add_intval_rule(struct _Maat_table_info_t* table,struct db_intval_rule_t* in HASH_add_by_id(scanner->group_hash, intval_rule->group_id, group_rule); } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,intval_rule->region_id,expr_id,TABLE_TYPE_INTVAL); + u_para=add_region_to_group(group_rule,intval_rule->region_id,district_id,expr_id,TABLE_TYPE_INTVAL); if(u_para==NULL) { return -1; @@ -1394,7 +1585,7 @@ int add_digest_rule(struct _Maat_table_info_t* table,struct db_digest_rule_t* db struct _Maat_group_rule_t* group_rule=NULL; GIE_digest_t* digest_rule=NULL; struct _Maat_group_rule_t* u_para=NULL; - int expr_id=0; + int expr_id=0,district_id=-1; group_rule=(struct _Maat_group_rule_t*)HASH_fetch_by_id(scanner->group_hash, db_digest_rule->group_id); if(group_rule==NULL) @@ -1403,7 +1594,7 @@ int add_digest_rule(struct _Maat_table_info_t* table,struct db_digest_rule_t* db HASH_add_by_id(scanner->group_hash, db_digest_rule->group_id, group_rule); } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,db_digest_rule->region_id,expr_id,TABLE_TYPE_DIGEST); + u_para=add_region_to_group(group_rule,db_digest_rule->region_id,expr_id,district_id,TABLE_TYPE_DIGEST); if(u_para==NULL) { return -1; @@ -1607,7 +1798,8 @@ void update_group_rule(struct _Maat_table_info_t* table,const char* table_line,s if(db_group_rule.is_valid==FALSE) { del_group_rule(table, &db_group_rule,scanner,logger); - table->cfg_num--; + //leave no trace for virtual group rule +// table->cfg_num--; } else { @@ -1623,7 +1815,7 @@ void update_group_rule(struct _Maat_table_info_t* table,const char* table_line,s else { //no need to free db_group_rule,it was saved in scanner->compile_hash - table->cfg_num++; +// table->cfg_num++; } } @@ -1642,20 +1834,46 @@ void update_expr_rule(struct _Maat_table_info_t* table,const char* table_line,st { struct db_str_rule_t* maat_str_rule=(struct db_str_rule_t*)malloc(sizeof(struct db_str_rule_t)); int ret=0,db_hexbin=0; - ret=sscanf(table_line,"%d\t%d\t%s\t%d\t%d\t%d\t%d",&(maat_str_rule->region_id) - ,&(maat_str_rule->group_id) - ,maat_str_rule->keywords - ,(int*)&(maat_str_rule->expr_type) - ,(int*)&(maat_str_rule->match_method) - ,&db_hexbin - ,&(maat_str_rule->is_valid)); - if(ret!=7) + switch(table->table_type) { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,invalid format of expr table %s:%s",table->table_name,table_line); - free(maat_str_rule); - maat_str_rule=NULL; - return; + case TABLE_TYPE_EXPR: + ret=sscanf(table_line,"%d\t%d\t%s\t%d\t%d\t%d\t%d",&(maat_str_rule->region_id) + ,&(maat_str_rule->group_id) + ,maat_str_rule->keywords + ,(int*)&(maat_str_rule->expr_type) + ,(int*)&(maat_str_rule->match_method) + ,&db_hexbin + ,&(maat_str_rule->is_valid)); + if(ret!=7) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , + "update error,invalid format of expr table %s:%s",table->table_name,table_line); + free(maat_str_rule); + maat_str_rule=NULL; + return; + } + break; + case TABLE_TYPE_EXPR_PLUS: + ret=sscanf(table_line,"%d\t%d\t%s\t%s\t%d\t%d\t%d\t%d",&(maat_str_rule->region_id) + ,&(maat_str_rule->group_id) + ,maat_str_rule->district + ,maat_str_rule->keywords + ,(int*)&(maat_str_rule->expr_type) + ,(int*)&(maat_str_rule->match_method) + ,&db_hexbin + ,&(maat_str_rule->is_valid)); + if(ret!=8) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , + "update error,invalid format of expr_plus table %s:%s",table->table_name,table_line); + free(maat_str_rule); + maat_str_rule=NULL; + return; + } + break; + default: + assert(0); + break; } switch(db_hexbin) { @@ -1830,6 +2048,14 @@ void update_ip_rule(struct _Maat_table_info_t* table,const char* table_line,stru if(ret>0) { table->cfg_num--; + if(ip_rule->addr_type==4) + { + table->ipv4_rule_cnt--; + } + else + { + table->ipv6_rule_cnt--; + } } } else @@ -1845,6 +2071,14 @@ void update_ip_rule(struct _Maat_table_info_t* table,const char* table_line,stru else { table->cfg_num++; + if(ip_rule->addr_type==4) + { + table->ipv4_rule_cnt++; + } + else + { + table->ipv6_rule_cnt++; + } } } error_out: @@ -2061,7 +2295,7 @@ void garbage_bury(MESA_lqueue_head garbage_q,void *logger) long data_size=0; const long q_cnt=MESA_lqueue_get_count(garbage_q); int i=0,bury_cnt=0; - int ref_cnt=0; + long long ref_cnt=0; int have_timeout=0; time_t now=time(NULL); for(i=0;igroup_rule); break; case GARBAGE_SCANNER: - ref_cnt=aligment_int_array_sum(bag->scanner->ref_cnt,bag->scanner->max_thread_num); + ref_cnt=aligment_int64_array_sum(bag->scanner->ref_cnt,bag->scanner->max_thread_num); if(ref_cnt==0) { @@ -2094,7 +2328,7 @@ void garbage_bury(MESA_lqueue_head garbage_q,void *logger) else { MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module, - "scanner %p version %d force destroyed,ref_cnt %d.", + "scanner %p version %d force destroyed,ref_cnt %lld.", bag->scanner,bag->scanner->version,ref_cnt); } @@ -2124,15 +2358,6 @@ void plugin_table_callback(struct _Maat_table_info_t* table,const char* table_li struct _plugin_table_info* p_table_cb=table->cb_info; char *p=NULL; pthread_mutex_lock(&(p_table_cb->plugin_mutex)); - - if(p_table_cb->is_called_started==0) - { - for(i=0;icb_plug_cnt;i++) - { - p_table_cb->cb_plug[i].start(p_table_cb->update_type,p_table_cb->cb_plug[i].u_para); - } - p_table_cb->is_called_started=1; - } if(p_table_cb->cb_plug_cnt>0) { for(i=0;icb_plug_cnt;i++) @@ -2197,10 +2422,10 @@ void maat_start_cb(unsigned int new_version,int update_type,void*u_para) struct _Maat_feather_t *feather=(struct _Maat_feather_t *)u_para; struct _Maat_table_info_t* p_table=NULL; struct _plugin_table_info* p_table_cb=NULL; - int i=0; + int i=0,j=0; if(update_type==CM_UPDATE_TYPE_FULL) { - feather->update_tmp_scanner=create_maat_scanner(new_version,feather->scan_thread_num,feather->garbage_q); + feather->update_tmp_scanner=create_maat_scanner(new_version,feather->scan_thread_num,feather->garbage_q,feather->rule_scan_type); MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module, "Full config version %u -> %u update start", feather->maat_version,new_version); @@ -2213,7 +2438,7 @@ void maat_start_cb(unsigned int new_version,int update_type,void*u_para) feather->maat_version,new_version); feather->maat_version=new_version; } - for(i=0;itable_cnt;i++) { p_table=feather->p_table_info[i]; if(p_table==NULL||p_table->table_type!=TABLE_TYPE_PLUGIN) @@ -2221,8 +2446,13 @@ void maat_start_cb(unsigned int new_version,int update_type,void*u_para) continue; } p_table_cb=p_table->cb_info; - p_table_cb->update_type=update_type; - assert(p_table_cb->is_called_started==0); + for(j=0;jcb_plug_cnt;j++) + { + if(p_table_cb->cb_plug[j].start!=NULL) + { + p_table_cb->cb_plug[j].start(update_type,p_table_cb->cb_plug[j].u_para); + } + } } return; } @@ -2249,17 +2479,13 @@ void maat_finish_cb(void* u_para) continue; } p_table_cb=p_table->cb_info; - if(p_table_cb->is_called_started==0) - { - continue; - } - p_table_cb->is_called_started=0; - pthread_mutex_lock(&(p_table_cb->plugin_mutex)); for(j=0;jcb_plug_cnt;j++) { - p_table_cb->cb_plug[j].finish(p_table_cb->cb_plug[j].u_para); + if(p_table_cb->cb_plug[j].finish!=NULL) + { + p_table_cb->cb_plug[j].finish(p_table_cb->cb_plug[j].u_para); + } } - pthread_mutex_unlock(&(p_table_cb->plugin_mutex)); } if(feather->update_tmp_scanner!=NULL) { @@ -2289,10 +2515,16 @@ void maat_finish_cb(void* u_para) else { MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module, - "Postpone config version %u (%d entries) load to rulescan.", + "Postpone config version %u %d entries load to rulescan.", feather->scanner->version,feather->scanner->cfg_num); } } + else + { + MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module, + "Version %d have no valid scan rules, plugin callback complete.", + feather->maat_version); + } return; } void maat_update_cb(const char* table_name,const char* line,void *u_para) @@ -2318,6 +2550,7 @@ void maat_update_cb(const char* table_name,const char* line,void *u_para) switch(feather->p_table_info[table_id]->table_type) { case TABLE_TYPE_EXPR: + case TABLE_TYPE_EXPR_PLUS: update_expr_rule(feather->p_table_info[table_id], line, scanner,feather->logger,feather->GROUP_MODE_ON); break; case TABLE_TYPE_IP: @@ -2349,9 +2582,11 @@ void *thread_rule_monitor(void *arg) const char* inc_cfg_dir=(const char*)feather->inc_dir; struct _Maat_scanner_t* old_scanner=NULL; long expr_wait_q_cnt=0; + int scan_dir_cnt=0; while(feather->still_working) { usleep(feather->scan_interval_ms*1000); + scan_dir_cnt++; config_monitor_traverse(feather->maat_version, inc_cfg_dir, maat_start_cb, @@ -2389,12 +2624,17 @@ void *thread_rule_monitor(void *arg) } } garbage_bury(feather->garbage_q,feather->logger); + if(feather->stat_on==1&&scan_dir_cnt%2==0)//output every 2 seconds + { + maat_stat_output(feather); + } } MESA_htable_destroy(feather->map_tablename2id,free); destroy_maat_scanner(feather->scanner); garbage_bury(feather->garbage_q,feather->logger); MESA_lqueue_destroy(feather->garbage_q,lqueue_destroy_cb,NULL); + FS_stop(&(feather->stat_handle)); int i=0,j=0; struct dynamic_array_t* d_array=NULL; @@ -2414,9 +2654,14 @@ void *thread_rule_monitor(void *arg) free(lines); } } - free(feather->p_table_info[i]); + destroy_table_info(feather->p_table_info[i]); feather->p_table_info[i]=NULL; } + aligment_int64_array_free(feather->thread_call_cnt); + aligment_int64_array_free(feather->inner_mid_cnt); + aligment_int64_array_free(feather->outer_mid_cnt); + aligment_int64_array_free(feather->hit_cnt); free(feather); return NULL; } + diff --git a/src/entry/Maat_rule_internal.h b/src/entry/Maat_rule_internal.h index 0c9586e..0dcdbda 100644 --- a/src/entry/Maat_rule_internal.h +++ b/src/entry/Maat_rule_internal.h @@ -5,13 +5,14 @@ #include #include +#include #include "dynamic_array.h" #include "UniversalBoolMatch.h" #include "rulescan.h" #include "mesa_fuzzy.h" #include "great_index_engine.h" - +#include "aligment_int64.h" #include #include @@ -30,15 +31,15 @@ typedef int atomic_t; #else #include #endif -#define CPU_CACHE_ALIGMENT 64 #define TRUE 1 #define FALSE 0 #define MAX_TABLE_NUM 256 -#define MAX_CHARSET_NUM 6 +#define MAX_CHARSET_NUM 16 #define MAX_TABLE_NAME_LEN 256 #define MAX_TABLE_LINE_SIZE (1024*4) #define MAX_EXPR_KEYLEN 1024 +#define MAX_DISTRICT_LEN 64 #define MAX_PLUGING_NUM 32 #define MAX_SCANNER_HIT_NUM 64 @@ -47,6 +48,7 @@ typedef int atomic_t; #define MAX_FAILED_NUM 128 +#define MAX_MAAT_STAT_NUM 64 #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif @@ -74,6 +76,7 @@ enum MAAT_TABLE_TYPE TABLE_TYPE_PLUGIN, TABLE_TYPE_INTVAL, TABLE_TYPE_DIGEST, + TABLE_TYPE_EXPR_PLUS, TABLE_TYPE_GROUP }; @@ -91,11 +94,13 @@ enum MAAT_MATCH_METHOD MATCH_METHOD_LEFT, MATCH_METHOD_FULL }; + struct db_str_rule_t { int region_id; int group_id; char keywords[MAX_EXPR_KEYLEN]; + char district[MAX_DISTRICT_LEN]; enum MAAT_EXPR_TYPE expr_type; enum MAAT_MATCH_METHOD match_method; int is_hexbin; @@ -162,12 +167,14 @@ struct op_expr_t { boolean_expr_t* p_expr; scan_rule_t* p_rules[MAAT_MAX_EXPR_ITEM_NUM]; + int no_effect_convert_cnt; }; struct _Maat_region_rule_t { int region_id; int expr_id; + int district_id; enum MAAT_TABLE_TYPE region_type; }; struct _Maat_group_rule_t @@ -223,20 +230,42 @@ struct _Maat_table_info_t int do_charset_merge; int cfg_num; int cross_cache_size; - int expr_rule_cnt; //expr_type=0,1,3 - int regex_rule_cnt; //expr_type=2 + union + { + int expr_rule_cnt; //expr_type=0,1,3 + int ipv4_rule_cnt; + }; + union + { + int regex_rule_cnt; //expr_type=2 + int ipv6_rule_cnt; + }; struct _plugin_table_info *cb_info; +//for stat>>>>>>>> + int stat_line_id; + mcore_long_t scan_cnt; + mcore_long_t scan_cpu_time; //nano + mcore_long_t input_bytes; + mcore_long_t stream_num; + mcore_long_t hit_cnt; }; -struct _scan_status_t + +struct _INNER_scan_status_t { - struct _Maat_feather_t* feather; - int thread_num; int cur_hit_cnt; int hit_group_cnt; int hit_group_size; unsigned int cur_hit_id[MAX_SCANNER_HIT_NUM]; unsigned int *hitted_group_id; }; +struct _OUTER_scan_status_t +{ + struct _Maat_feather_t* feather; + unsigned short thread_num; + unsigned short is_set_district; + int district_id; + struct _INNER_scan_status_t* inner; +}; enum maat_garbage_type { GARBAGE_SCANNER=0, @@ -273,13 +302,15 @@ struct _Maat_scanner_t { int version; time_t last_update_time; - int *ref_cnt; //optimized for cache_alignment 64 + long long *ref_cnt; //optimized for cache_alignment 64 rule_scanner_t region; pthread_rwlock_t digest_rwlock[MAX_TABLE_NUM]; GIE_handle_t* digest_handle[MAX_TABLE_NUM]; MESA_htable_handle region_hash; MESA_htable_handle group_hash; MESA_htable_handle compile_hash; + MESA_htable_handle district_map; + unsigned int district_num; unsigned int cfg_num; unsigned int exprid_generator; MESA_lqueue_head region_update_q; @@ -296,17 +327,32 @@ struct _Maat_feather_t struct _Maat_scanner_t *update_tmp_scanner; MESA_lqueue_head garbage_q; int table_cnt; + int GROUP_MODE_ON; + int still_working; + int scan_interval_ms; + int effect_interval_ms; + int stat_on; + int perf_on; struct _Maat_table_info_t *p_table_info[MAX_TABLE_NUM]; MESA_htable_handle map_tablename2id; void* logger; int maat_version; int scan_thread_num; + int rule_scan_type; char inc_dir[MAX_TABLE_NAME_LEN]; char full_dir[MAX_TABLE_NAME_LEN]; - int GROUP_MODE_ON; - int still_working; - int scan_interval_ms; - int effect_interval_ms; + char stat_file[MAX_TABLE_NAME_LEN]; +//for stat>>>> + screen_stat_handle_t stat_handle; + int total_stat_id; + int fs_status_id[MAX_MAAT_STAT_NUM]; + int fs_column_id[MAX_MAAT_STAT_NUM]; + mcore_long_t outer_mid_cnt; + mcore_long_t inner_mid_cnt; + mcore_long_t hit_cnt; + mcore_long_t thread_call_cnt;//size indicate by scan_thread_num, + long long total_scan_bytes; + long long total_scan_cnt; }; struct _maat_garbage_t { @@ -325,7 +371,7 @@ struct _maat_garbage_t void garbage_bagging(enum maat_garbage_type type,void *p,MESA_lqueue_head garbage_q); void garbage_bury(MESA_lqueue_head garbage_q,void *logger); void make_group_set(const struct _Maat_compile_rule_t* compile_rule,universal_bool_expr_t* a_set); -int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_info_path,void*logger); +int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_info_path,int max_thread_num,void* logger); void maat_start_cb(unsigned int new_version,int update_type,void*u_para); void maat_update_cb(const char* table_name,const char* line,void *u_para); void maat_finish_cb(void* u_para); @@ -340,5 +386,11 @@ inline void ipv6_ntoh(unsigned int *v6_addr) } return; } +void maat_stat_init(struct _Maat_feather_t* feather); +void maat_stat_table(struct _Maat_table_info_t* p_table,int scan_len,struct timespec* start, struct timespec* end,int thread_num); +void maat_stat_output(struct _Maat_feather_t* feather); + + + #endif diff --git a/src/entry/Maat_stat.cpp b/src/entry/Maat_stat.cpp new file mode 100644 index 0000000..6a32535 --- /dev/null +++ b/src/entry/Maat_stat.cpp @@ -0,0 +1,253 @@ +#include "Maat_rule_internal.h" +#include "aligment_int64.h" +#include +#include +enum MAAT_FS_STATUS{ + STATUS_VERSION=0, + STATUS_THRED_NUM, + STATUS_TABLE_NUM, + STATUS_OUTER_MID_NUM, + STATUS_INNER_MID_NUM, + STATUS_GARBAGE_QSIZE, + STATUS_TOTAL_SCAN_LEN, + STATUS_TOTAL_SCAN_CNT, +}; + +enum MAAT_FS_COLUMN +{ + COLUMN_TABLE_RULE_NUM=0, + COLUMN_TABLE_REGEX_NUM, + COLUMN_TABLE_STREAM_NUM, + COLUMN_TABLE_SCAN_CNT, + COLUMN_TABLE_SCAN_BYTES, + COLUMN_TABLE_CPU_TIME,//microseconds + COLUMN_TABLE_HIT_CNT, +}; +void maat_stat_init(struct _Maat_feather_t* feather) +{ + int value=0; + int i=0; + struct _Maat_table_info_t* p_table=NULL; + + feather->stat_handle=FS_create_handle(); + FS_set_para(feather->stat_handle, OUTPUT_DEVICE, feather->stat_file, strlen(feather->stat_file)+1); + value=1; + FS_set_para(feather->stat_handle, PRINT_MODE, &value, sizeof(value)); + value=0; + FS_set_para(feather->stat_handle, CREATE_THREAD, &value, sizeof(value)); + + feather->fs_status_id[STATUS_VERSION]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"version"); + feather->fs_status_id[STATUS_THRED_NUM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"active_thread"); + feather->fs_status_id[STATUS_TABLE_NUM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"table_num"); + feather->fs_status_id[STATUS_OUTER_MID_NUM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"outer_mid"); + feather->fs_status_id[STATUS_INNER_MID_NUM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"inner_mid"); + feather->fs_status_id[STATUS_GARBAGE_QSIZE]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"garbage_num"); + feather->fs_status_id[STATUS_TOTAL_SCAN_LEN]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"scan_bytes"); + feather->fs_status_id[STATUS_TOTAL_SCAN_CNT]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"scan_times"); + + + feather->fs_column_id[COLUMN_TABLE_RULE_NUM]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_CURRENT,"rule"); + feather->fs_column_id[COLUMN_TABLE_REGEX_NUM]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_CURRENT,"regex"); + feather->fs_column_id[COLUMN_TABLE_STREAM_NUM]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_CURRENT,"stream"); + feather->fs_column_id[COLUMN_TABLE_SCAN_BYTES]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_SPEED,"IN_Bps"); + if(feather->perf_on==1) + { + feather->fs_column_id[COLUMN_TABLE_CPU_TIME]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_SPEED,"cpu_us"); + value=feather->fs_column_id[COLUMN_TABLE_CPU_TIME]; + FS_set_para(feather->stat_handle, ID_INVISBLE, &value, sizeof(value)); + FS_register_ratio(feather->stat_handle, + feather->fs_column_id[COLUMN_TABLE_SCAN_BYTES], + feather->fs_column_id[COLUMN_TABLE_CPU_TIME], + 1000000, //microsecond to second + FS_STYLE_COLUMN, + FS_CALC_SPEED, + "PROC_Bps"); + } + feather->fs_column_id[COLUMN_TABLE_SCAN_CNT]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_SPEED,"IN_Tps"); + if(feather->perf_on==1) + { + FS_register_ratio(feather->stat_handle, + feather->fs_column_id[COLUMN_TABLE_SCAN_CNT], + feather->fs_column_id[COLUMN_TABLE_CPU_TIME], + 1000000, //microsecond to second + FS_STYLE_COLUMN, + FS_CALC_SPEED, + "PROC_Tps"); + } + feather->fs_column_id[COLUMN_TABLE_HIT_CNT]=FS_register(feather->stat_handle, FS_STYLE_COLUMN, FS_CALC_SPEED,"hit_cnt"); + value=feather->fs_column_id[COLUMN_TABLE_HIT_CNT]; + FS_set_para(feather->stat_handle, ID_INVISBLE, &value, sizeof(value)); + FS_register_ratio(feather->stat_handle, + feather->fs_column_id[COLUMN_TABLE_HIT_CNT], + feather->fs_column_id[COLUMN_TABLE_SCAN_CNT], + 1, + FS_STYLE_COLUMN, + FS_CALC_SPEED, + "hit_rate"); + feather->total_stat_id=FS_register(feather->stat_handle, FS_STYLE_LINE, FS_CALC_CURRENT,"Sum"); + for(i=0;ip_table_info[i]; + if(p_table==NULL||p_table->table_type==TABLE_TYPE_PLUGIN + ||p_table->table_type==TABLE_TYPE_GROUP + ||p_table->table_type==TABLE_TYPE_COMPILE) + { + continue; + } + p_table->stat_line_id=FS_register(feather->stat_handle, FS_STYLE_LINE, FS_CALC_CURRENT,p_table->table_name); + } + FS_start(feather->stat_handle); + return; +} +void maat_stat_table(struct _Maat_table_info_t* p_table,int scan_len,struct timespec* start, struct timespec* end,int thread_num) +{ + aligment_int64_array_add(p_table->scan_cnt,thread_num,1); + aligment_int64_array_add(p_table->input_bytes,thread_num,scan_len); + if(start!=NULL&&end!=NULL) + { + aligment_int64_array_add(p_table->scan_cpu_time,thread_num,(end->tv_sec-start->tv_sec)*1000000000+end->tv_nsec-start->tv_nsec); + } + return; +} +void maat_stat_output(struct _Maat_feather_t* feather) +{ + long value=0; + long long total_cfg_num=0, total_input_bytes=0, total_regex_num=0,total_hit_cnt=0; + long long total_scan_cnt=0, total_cpu_time=0,total_stream_cnt=0,active_thread_num=0; + long long table_stream_num=0,table_scan_cnt=0,table_input_bytes=0,table_scan_cpu_time=0,table_hit_cnt=0; + long long outer_mid_cnt=0,inner_mid_cnt=0; + int i=0; + time_t now; + struct _Maat_table_info_t* p_table=NULL; + time(&now); + active_thread_num=aligment_int64_array_cnt(feather->thread_call_cnt, feather->scan_thread_num); + outer_mid_cnt=aligment_int64_array_sum(feather->outer_mid_cnt,feather->scan_thread_num); + inner_mid_cnt=aligment_int64_array_sum(feather->inner_mid_cnt,feather->scan_thread_num); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_VERSION], 0,FS_OP_SET,feather->maat_version); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_THRED_NUM], 0,FS_OP_SET,active_thread_num); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_TABLE_NUM], 0,FS_OP_SET,feather->table_cnt); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_OUTER_MID_NUM], 0,FS_OP_SET,outer_mid_cnt); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_INNER_MID_NUM], 0,FS_OP_SET,inner_mid_cnt); + + value=MESA_lqueue_get_count(feather->garbage_q); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_GARBAGE_QSIZE], 0,FS_OP_SET,value); + + for(i=0;ip_table_info[i]; + if(p_table==NULL||p_table->table_type==TABLE_TYPE_PLUGIN + ||p_table->table_type==TABLE_TYPE_GROUP + ||p_table->table_type==TABLE_TYPE_COMPILE) + { + continue; + } + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_RULE_NUM], + FS_OP_SET, + p_table->cfg_num); + total_cfg_num+=p_table->cfg_num; + + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_REGEX_NUM], + FS_OP_SET, + p_table->regex_rule_cnt); + total_regex_num+= p_table->regex_rule_cnt; + + table_stream_num=aligment_int64_array_sum(p_table->stream_num,feather->scan_thread_num); + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_STREAM_NUM], + FS_OP_SET, + table_stream_num); + total_stream_cnt+= table_stream_num; + + table_scan_cnt=aligment_int64_array_sum(p_table->scan_cnt,feather->scan_thread_num); + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_SCAN_CNT], + FS_OP_SET, + table_scan_cnt); + total_scan_cnt+=table_scan_cnt; + + table_input_bytes=aligment_int64_array_sum(p_table->input_bytes,feather->scan_thread_num); + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_SCAN_BYTES], + FS_OP_SET, + table_input_bytes); + total_input_bytes+=table_input_bytes; + if(feather->perf_on==1) + { + table_scan_cpu_time=aligment_int64_array_sum(p_table->scan_cpu_time,feather->scan_thread_num); + table_scan_cpu_time/=1000; + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_CPU_TIME], + FS_OP_SET, + table_scan_cpu_time); + total_cpu_time+=table_scan_cpu_time; + } + + table_hit_cnt=aligment_int64_array_sum(p_table->hit_cnt,feather->scan_thread_num); + FS_operate(feather->stat_handle, + p_table->stat_line_id, + feather->fs_column_id[COLUMN_TABLE_HIT_CNT], + FS_OP_SET, + table_hit_cnt); + //total hit count stat in region_compile + + } + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_RULE_NUM], + FS_OP_SET, + total_cfg_num); + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_REGEX_NUM], + FS_OP_SET, + total_regex_num); + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_STREAM_NUM], + FS_OP_SET, + total_stream_cnt); + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_SCAN_CNT], + FS_OP_SET, + total_scan_cnt); + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_SCAN_BYTES], + FS_OP_SET, + total_input_bytes); + if(feather->perf_on==1) + { + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_CPU_TIME], + FS_OP_SET, + total_cpu_time); + } + total_hit_cnt=aligment_int64_array_sum(feather->hit_cnt,feather->scan_thread_num); + FS_operate(feather->stat_handle, + feather->total_stat_id, + feather->fs_column_id[COLUMN_TABLE_HIT_CNT], + FS_OP_SET, + total_hit_cnt); + feather->total_scan_bytes=total_input_bytes; + feather->total_scan_cnt=total_scan_cnt; + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_TOTAL_SCAN_LEN], 0,FS_OP_SET,feather->total_scan_bytes); + FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_TOTAL_SCAN_CNT], 0,FS_OP_SET,feather->total_scan_cnt); + FS_passive_output(feather->stat_handle); + return; +} + diff --git a/src/entry/Makefile b/src/entry/Makefile index 539f22a..4b72255 100644 --- a/src/entry/Makefile +++ b/src/entry/Makefile @@ -6,7 +6,7 @@ CCC = g++ CFLAGS = -Wall -g -fPIC CFLAGS += $(OPTFLAGS) LDDICTATOR = -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,realloc -LDFLAGS = -lMESA_handle_logger -lMESA_htable -lpthread -lm -lrulescan -lpcre +LDFLAGS = -lMESA_handle_logger -lMESA_htable -lpthread -lrt -lm -lrulescan -lpcre -lMESA_field_stat2 #LDFLAGS += $(LDDICTATOR) MAILLIB = ../lib @@ -15,8 +15,8 @@ H_DIR =-I$(G_H_DIR) -I../../inc LIBMAAT = libmaatframe.a LIBMAAT_SO = libmaatframe.so -OBJS=config_monitor.o Maat_rule.o Maat_api.o UniversalBoolMatch.o dynamic_array.o cJSON.o json2iris.o map_str2int.o\ - interval_index.o great_index_engine.o mesa_fuzzy.o +OBJS=config_monitor.o Maat_rule.o Maat_api.o Maat_stat.o UniversalBoolMatch.o dynamic_array.o cJSON.o\ + json2iris.o map_str2int.o interval_index.o great_index_engine.o mesa_fuzzy.o rbtree.o .c.o: $(CC) -c $(CFLAGS) -I. $(H_DIR) $< diff --git a/src/entry/aligment_int64.h b/src/entry/aligment_int64.h new file mode 100644 index 0000000..1ae4200 --- /dev/null +++ b/src/entry/aligment_int64.h @@ -0,0 +1,52 @@ +#ifndef H_ALIGMENT_INT64_H_INCLUDE +#define H_ALIGMENT_INT64_H_INCLUDE + +#include + +#define CPU_CACHE_ALIGMENT 64 +typedef long long* mcore_long_t; + +inline long long *aligment_int64_array_alloc(int size) +{ + long long *ret=NULL; + ret=(long long*)calloc(CPU_CACHE_ALIGMENT,size); + return ret; +} +inline long long aligment_int64_array_sum(mcore_long_t array,int size) +{ + long long sum=0; + int offset=0,i=0; + for(i=0;i0) + { + cnt++; + } + } + return cnt; +} +inline void aligment_int64_array_free(mcore_long_t array) +{ + free(array); +} + +#endif + diff --git a/src/entry/great_index_engine.c b/src/entry/great_index_engine.c index 683085f..c907384 100644 --- a/src/entry/great_index_engine.c +++ b/src/entry/great_index_engine.c @@ -97,7 +97,7 @@ GIE_handle_t * GIE_create(const GIE_create_para_t * para) idtable_args.hash_slot_size = HTABLE_SIZE; idtable_args.max_elem_num = 4 * HTABLE_SIZE; idtable_args.expire_time = 0; - idtable_args.eliminate_type = HASH_ELIMINATE_ALGO_LRU; + idtable_args.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; idtable_args.key_comp = NULL; idtable_args.key2index = NULL; idtable_args.data_free = idtable_free; @@ -108,7 +108,7 @@ GIE_handle_t * GIE_create(const GIE_create_para_t * para) indextable_args.hash_slot_size = HTABLE_SIZE; indextable_args.max_elem_num = 4 * HTABLE_SIZE; indextable_args.expire_time = 0; - indextable_args.eliminate_type = HASH_ELIMINATE_ALGO_LRU; + indextable_args.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; indextable_args.key_comp = NULL; indextable_args.key2index = NULL; indextable_args.data_free = indextable_free; diff --git a/src/inc_internal/great_index_engine.h b/src/entry/great_index_engine.h similarity index 100% rename from src/inc_internal/great_index_engine.h rename to src/entry/great_index_engine.h diff --git a/src/entry/interval_index.c b/src/entry/interval_index.c index 581acbe..b993a3f 100644 --- a/src/entry/interval_index.c +++ b/src/entry/interval_index.c @@ -1,7 +1,17 @@ -#include -#include -#include"interval_index.h" - +/********************************************************************* + * File: + * interval_index.c + * Author: + * TangQi + * E-mail: + * tangqi@iie.ac.cn + *********************************************************************/ +#include +#include +#include +#include "interval_index.h" +#include "rbtree.h" +#include "rbtree_augmented.h" /** * There is a trick here. In order to hide specific @@ -16,73 +26,113 @@ * Structure of inner segment **/ typedef struct __IVI_shadow_seg_t{ - IVI_seg_t lightseg; - TAILQ_ENTRY(__IVI_shadow_seg_t) ENTRY; + IVI_seg_t lightseg; /* interval for user, including left edge, right edge, and user's data */ + struct rb_node rb; /* node of rb-tree */ + OFFSET_TYPE max; /* max edge of subtree */ }IVI_shadow_seg_t; -TAILQ_HEAD(TQ, __IVI_shadow_seg_t); - /* Structure of inner InterVal Index */ typedef struct __IVI_shadow_t{ - struct TQ ivi_queue; + struct rb_root root; + + /* statistics */ int segs_cnt; OFFSET_TYPE segs_length; + unsigned long long mem_occupy; //do not include user data }IVI_shadow_t; -/** - * new is closer to head or tail ? - * Return 1 if closer to head than tail - * Else return 0 - */ -int closer_to_head(IVI_shadow_seg_t * head, IVI_shadow_seg_t * tail, OFFSET_TYPE target) + + +IVI_seg_t * IVI_first_seg(IVI_t * handler) { - if(head == NULL || tail == NULL) - return 1; - S_OFFSET_TYPE tmp1 = (S_OFFSET_TYPE)(target - head->lightseg.left); - S_OFFSET_TYPE tmp2 = (S_OFFSET_TYPE)(target - tail->lightseg.left); - S_OFFSET_TYPE distance_to_head = tmp1 > 0 ? tmp1 : -tmp1; - S_OFFSET_TYPE distance_to_tail = tmp2 > 0 ? tmp2 : -tmp2; - return (distance_to_tail - distance_to_head > 0); + assert(handler != NULL); + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + struct rb_node *first_node = rb_first(&(shadow_ivi->root)); + if(first_node == NULL) + return NULL; + return (IVI_seg_t *)(rb_entry(first_node, IVI_shadow_seg_t, rb)); +} + + +IVI_seg_t * IVI_last_seg(IVI_t * handler) +{ + assert(handler != NULL); + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + struct rb_node *last_node = rb_last(&(shadow_ivi->root)); + if(last_node == NULL) + return NULL; + return (IVI_seg_t *)(rb_entry(last_node, IVI_shadow_seg_t, rb)); +} + + + +IVI_seg_t * IVI_prev_seg(IVI_seg_t * seg) +{ + assert(seg != NULL); + IVI_shadow_seg_t * shadow_seg = (IVI_shadow_seg_t *)seg; + struct rb_node * prev_node = rb_prev(&(shadow_seg->rb)); + if(prev_node == NULL) + return NULL; + return (IVI_seg_t *)(rb_entry(prev_node, IVI_shadow_seg_t, rb)); +} + + + +IVI_seg_t * IVI_next_seg(IVI_seg_t * seg) +{ + assert(seg != NULL); + IVI_shadow_seg_t * shadow_seg = (IVI_shadow_seg_t *)seg; + struct rb_node * next_node = rb_next(&(shadow_seg->rb)); + if(next_node == NULL) + return NULL; + return (IVI_seg_t *)(rb_entry(next_node, IVI_shadow_seg_t, rb)); } IVI_seg_t * IVI_prev_continuous_seg(IVI_seg_t * seg) { - if(NULL == seg) + assert(seg != NULL); + IVI_shadow_seg_t * shadow_seg = (IVI_shadow_seg_t *)seg; + struct rb_node * prev_node = rb_prev(&(shadow_seg->rb)); + if(prev_node == NULL) { return NULL; } - - IVI_shadow_seg_t * _seg = (IVI_shadow_seg_t *)seg; - IVI_shadow_seg_t * prev = TAILQ_PREV(_seg, TQ, ENTRY); - if(NULL == prev) + IVI_seg_t * prev_seg = (IVI_seg_t *)(rb_entry(prev_node, IVI_shadow_seg_t, rb)); + if(!continuous(prev_seg->right, seg->left)) { return NULL; } - if(continuous((prev->lightseg).right, seg->left)) - return (IVI_seg_t *)prev; - return NULL; + return prev_seg; } IVI_seg_t * IVI_next_continuous_seg(IVI_seg_t * seg) { - if(NULL == seg) + assert(seg != NULL); + IVI_shadow_seg_t * shadow_seg = (IVI_shadow_seg_t *)seg; + struct rb_node * next_node = rb_next(&(shadow_seg->rb)); + if(next_node == NULL) { return NULL; } - IVI_shadow_seg_t * _seg = (IVI_shadow_seg_t *)seg; - IVI_shadow_seg_t * next = TAILQ_NEXT(_seg, ENTRY); - if(NULL == next) + IVI_seg_t * next_seg = (IVI_seg_t *)(rb_entry(next_node, IVI_shadow_seg_t, rb)); + if(!continuous(seg->right, next_seg->left)) { return NULL; } - if(continuous(seg->right, (next->lightseg).left)) - return (IVI_seg_t *)next; - return NULL; + return next_seg; +} + + +static inline int __is_overlapped(OFFSET_TYPE left1, OFFSET_TYPE right1, OFFSET_TYPE left2, OFFSET_TYPE right2) +{ + if(!after(left1, right2) && !after(left2, right1)) + return 1; + return 0; } @@ -152,13 +202,42 @@ Relation_t IVI_relative_position(IVI_seg_t * seg1, IVI_seg_t * seg2) IVI_t * IVI_create(void) { IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)malloc(sizeof(IVI_shadow_t)); - TAILQ_INIT(&(shadow_ivi->ivi_queue)); + shadow_ivi->root = RB_ROOT; //init rb tree's root shadow_ivi->segs_cnt = 0; shadow_ivi->segs_length = 0; + shadow_ivi->mem_occupy = sizeof(IVI_shadow_t); return (IVI_t *)shadow_ivi; } + +static void __free_rb_tree(struct rb_node * root, IVI_callback_t cb, void * usr_para) +{ + if(root == NULL) + { + return; + } + if(root->rb_left != NULL) + { + __free_rb_tree(root->rb_left, cb, usr_para); + } + if(root->rb_right != NULL) + { + __free_rb_tree(root->rb_right, cb, usr_para); + } + /* free user data */ + IVI_shadow_seg_t * shadow_seg = rb_entry(root, IVI_shadow_seg_t, rb); + if(cb != NULL) + { + cb((IVI_seg_t *)shadow_seg, usr_para); + } + + /* free seg */ + free(shadow_seg); + shadow_seg = NULL; + return; +} + /** * Name: * IVI_destroy @@ -177,26 +256,11 @@ void IVI_destroy(IVI_t * handler, IVI_callback_t cb, void * usr_para) { return; } - IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; - IVI_shadow_seg_t * tmpseg = TAILQ_FIRST(&(shadow_ivi->ivi_queue)); - IVI_shadow_seg_t * tmp; - /* Free each seg in IVI */ - while(tmpseg != NULL) - { - tmp = TAILQ_NEXT(tmpseg, ENTRY); - /* Free *data in seg */ - if(NULL != cb) - { - cb(&(tmpseg->lightseg), usr_para); - } - free(tmpseg); - tmpseg = tmp; - } - - /* Free IVI */ + __free_rb_tree(shadow_ivi->root.rb_node, cb, usr_para); free(shadow_ivi); handler = NULL; + return; } @@ -224,6 +288,7 @@ IVI_seg_t * IVI_seg_malloc(OFFSET_TYPE left, OFFSET_TYPE right, void * data) shadow_seg->lightseg.left = left; shadow_seg->lightseg.right= right; shadow_seg->lightseg.data = data; + shadow_seg->max = 0; return (IVI_seg_t *)shadow_seg; } @@ -244,6 +309,8 @@ IVI_seg_t * IVI_seg_malloc(OFFSET_TYPE left, OFFSET_TYPE right, void * data) **/ void IVI_seg_free(IVI_seg_t * seg, IVI_callback_t cb, void * usr_para) { + assert(seg != NULL); + /* Free user data first */ if(cb != NULL) { @@ -257,6 +324,70 @@ void IVI_seg_free(IVI_seg_t * seg, IVI_callback_t cb, void * usr_para) } + + +static inline OFFSET_TYPE __interval_tree_get_subtree_max(IVI_shadow_seg_t * node) +{ + OFFSET_TYPE max = node->lightseg.right, subtree_max; + if(node->rb.rb_left) + { + subtree_max = (rb_entry(node->rb.rb_left, IVI_shadow_seg_t, rb))->max; + if(before(max, subtree_max)) + max = subtree_max; + } + if(node->rb.rb_right) + { + subtree_max = (rb_entry(node->rb.rb_right, IVI_shadow_seg_t, rb))->max; + if(before(max, subtree_max)) + max = subtree_max; + } + return max; +} + + +static void __interval_tree_augment_propagate(struct rb_node * rb, struct rb_node * stop) +{ + while(rb != stop) + { + IVI_shadow_seg_t * node = rb_entry(rb, IVI_shadow_seg_t, rb); + OFFSET_TYPE subtree_max = __interval_tree_get_subtree_max(node); + if(node->max == subtree_max) + { + break; + } + node->max = subtree_max; + rb = rb_parent(&node->rb); + } + return; +} + + +static void __interval_tree_augment_copy(struct rb_node * rb_old, struct rb_node * rb_new) +{ + IVI_shadow_seg_t * old = rb_entry(rb_old, IVI_shadow_seg_t, rb); + IVI_shadow_seg_t * new = rb_entry(rb_new, IVI_shadow_seg_t, rb); + new->max = old->max; + return; +} + + +static void __interval_tree_augment_rotate(struct rb_node * rb_old, struct rb_node * rb_new) +{ + IVI_shadow_seg_t * old = rb_entry(rb_old, IVI_shadow_seg_t, rb); + IVI_shadow_seg_t * new = rb_entry(rb_new, IVI_shadow_seg_t, rb); + new->max = old->max; + old->max = __interval_tree_get_subtree_max(old); + return; +} + + +static const struct rb_augment_callbacks __interval_tree_augment_callbacks = { + __interval_tree_augment_propagate, + __interval_tree_augment_copy, + __interval_tree_augment_rotate +}; + + /** * Name: * IVI_insert @@ -273,74 +404,49 @@ void IVI_seg_free(IVI_seg_t * seg, IVI_callback_t cb, void * usr_para) **/ int IVI_insert(IVI_t * handler, IVI_seg_t * seg) { - IVI_shadow_t * shadow_ivi; - IVI_shadow_seg_t *head, *tail, *new_seg, *tmp_seg; - if(NULL == handler || NULL == seg) { return -1; } - shadow_ivi = (IVI_shadow_t *)handler; - new_seg = (IVI_shadow_seg_t *)seg; - head = TAILQ_FIRST(&(shadow_ivi->ivi_queue)); - tail = TAILQ_LAST(&(shadow_ivi->ivi_queue), TQ); - - if(closer_to_head(head, tail, seg->left)) + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + struct rb_root * root = &(shadow_ivi->root); + OFFSET_TYPE left = seg->left, right = seg->right; + struct rb_node **link = &root->rb_node, *rb_parent = NULL; + IVI_shadow_seg_t * parent = NULL; + IVI_shadow_seg_t * new_seg = (IVI_shadow_seg_t *)seg; + while(*link) { - TAILQ_FOREACH(tmp_seg, &(shadow_ivi->ivi_queue), ENTRY) + rb_parent = *link; + parent = rb_entry(rb_parent, IVI_shadow_seg_t, rb); + /* is overlapped */ + if(__is_overlapped(left, right, parent->lightseg.left, parent->lightseg.right)) + { + //overlapped, return + return -1; + } + + if(before(parent->max, right)) { - /* Find the first seg whose left is bigger than given seg's right, we will insert new seg before it */ - if(after(tmp_seg->lightseg.left, new_seg->lightseg.right)) - { - TAILQ_INSERT_BEFORE(tmp_seg, new_seg, ENTRY); - shadow_ivi->segs_cnt ++; - shadow_ivi->segs_length += (seg->right - seg->left + 1); - return 0; - } - else if(before(tmp_seg->lightseg.right, new_seg->lightseg.left)) - { - continue; - } - else /* Overlap */ - { - return -1; - } + parent->max = right; } - - /* If have searched to the end of list, we will inset it to the tail */ - TAILQ_INSERT_TAIL(&(shadow_ivi->ivi_queue), new_seg, ENTRY); - shadow_ivi->segs_cnt ++; - shadow_ivi->segs_length += (seg->right - seg->left + 1); - } - else - { - TAILQ_FOREACH_REVERSE(tmp_seg, &(shadow_ivi->ivi_queue), TQ, ENTRY) + if(before(left, parent->lightseg.left)) { - /* Find the first seg whose right is smaller than given seg's left, we will insert new seg after it */ - if(before(tmp_seg->lightseg.right, new_seg->lightseg.left)) - { - TAILQ_INSERT_AFTER(&(shadow_ivi->ivi_queue), tmp_seg, new_seg, ENTRY); - shadow_ivi->segs_cnt ++; - shadow_ivi->segs_length += (seg->right - seg->left + 1); - return 0; - } - else if(after(tmp_seg->lightseg.left, new_seg->lightseg.right)) - { - continue; - } - else /* Overlap */ - { - return -1; - } + link = &parent->rb.rb_left; + } + else + { + link = &parent->rb.rb_right; } - - /* If have searched to the head of list, we will inset it to the head */ - TAILQ_INSERT_HEAD(&(shadow_ivi->ivi_queue), new_seg, ENTRY); - shadow_ivi->segs_cnt ++; - shadow_ivi->segs_length += (seg->right - seg->left + 1); } + new_seg->max = right; + rb_link_node(&new_seg->rb, rb_parent, link); + rb_insert_augmented(&new_seg->rb, root, &__interval_tree_augment_callbacks); + /* updata statistics */ + shadow_ivi->segs_cnt ++; + shadow_ivi->segs_length += seg->right - seg->left + 1; + shadow_ivi->mem_occupy += sizeof(IVI_shadow_seg_t); return 0; } @@ -367,16 +473,56 @@ int IVI_remove(IVI_t * handler, IVI_seg_t * seg) } IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; - IVI_shadow_seg_t * shadow_seg = (IVI_shadow_seg_t *)seg; + struct rb_root * root = &(shadow_ivi->root); + IVI_shadow_seg_t * new_seg = (IVI_shadow_seg_t *)seg; + rb_erase_augmented(&new_seg->rb, root, &__interval_tree_augment_callbacks); - TAILQ_REMOVE(&(shadow_ivi->ivi_queue), shadow_seg, ENTRY); + /* updata statistics */ shadow_ivi->segs_cnt --; - shadow_ivi->segs_length -= (seg->right - seg->left + 1); + shadow_ivi->segs_length -= seg->right - seg->left + 1; + shadow_ivi->mem_occupy -= sizeof(IVI_shadow_seg_t); + return 0; } +static struct rb_node * __min_interval_search_from(struct rb_node * node, OFFSET_TYPE left, OFFSET_TYPE right) +{ + if(node == NULL) + { + return NULL; + } + IVI_shadow_seg_t * seg = rb_entry(node, IVI_shadow_seg_t, rb); + IVI_shadow_seg_t * left_seg = rb_entry(node->rb_left, IVI_shadow_seg_t, rb); + if(node->rb_left != NULL && !before(left_seg->max, left)) + { + struct rb_node * ret = __min_interval_search_from(node->rb_left, left, right); + if(ret != NULL) + { + return ret; + } + else if(__is_overlapped(left, right, seg->lightseg.left, seg->lightseg.right)) + { + return node; + } + else + { + return NULL; + } + } + else if(__is_overlapped(left, right, seg->lightseg.left, seg->lightseg.right)) + { + return node; + } + else + { + return __min_interval_search_from(node->rb_right, left, right); + } +} + + + /** * Name: * IVI_query @@ -397,115 +543,34 @@ int IVI_remove(IVI_t * handler, IVI_seg_t * seg) **/ int IVI_query(IVI_t * handler, OFFSET_TYPE left, OFFSET_TYPE right, IVI_seg_t *** segs) { - IVI_shadow_t * shadow_ivi; - IVI_shadow_seg_t *head, *tail, *tmp, *left_tmp, *right_tmp; - int interval_cnt = 0, i; - if(NULL == handler || after(left, right)) { + //augments error return -1; } - shadow_ivi = (IVI_shadow_t *)handler; - head = TAILQ_FIRST(&(shadow_ivi->ivi_queue)); - tail = TAILQ_LAST(&(shadow_ivi->ivi_queue), TQ); + int interval_cnt = 0, max_cnt = 8; + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + struct rb_node * root = shadow_ivi->root.rb_node; + struct rb_node * min_overlap = __min_interval_search_from(root, left, right); + struct rb_node * tmp_node = min_overlap; - /* Traverse from head or tail? We need to decide */ - if(closer_to_head(head, tail, left)) + *segs = (IVI_seg_t **)malloc(max_cnt * sizeof(IVI_seg_t *)); + while (tmp_node != NULL) { - tmp = head; - while(tmp != NULL) + IVI_seg_t * tmp_seg = (IVI_seg_t *)(rb_entry(tmp_node, IVI_shadow_seg_t, rb)); + if(!__is_overlapped(tmp_seg->left, tmp_seg->right, left, right)) { - if(after(left, tmp->lightseg.right)) - { - tmp = TAILQ_NEXT(tmp, ENTRY); - } - else - { - /* Get the seg which left is in or before*/ - left_tmp = tmp; - break; - } + break; } - if(tmp == NULL) + if(interval_cnt > max_cnt) { - *segs = NULL; - return 0; - } - - /* Get the num of overlapped segs */ - while(tmp != NULL) - { - if(!before(right, tmp->lightseg.left)) - { - tmp = TAILQ_NEXT(tmp, ENTRY); - interval_cnt ++; - } - else - { - break; - } - } - - tmp = left_tmp; - if(interval_cnt == 0) - { - *segs = NULL; - return 0; - } - *segs = (IVI_seg_t **)malloc(interval_cnt * sizeof(IVI_seg_t *)); - for(i = 0; i < interval_cnt; i++) - { - (*segs)[i] = (IVI_seg_t *)tmp; - tmp = TAILQ_NEXT(tmp, ENTRY); - } - } - else - { - tmp = tail; - while(tmp != NULL) - { - if(before(right, tmp->lightseg.left)) - { - tmp = TAILQ_PREV(tmp, TQ, ENTRY); - } - else - { - right_tmp = tmp; - break; - } - } - if(tmp == NULL) - { - *segs = NULL; - return 0; - } - - /* Get the num of overlapped segs */ - while(tmp != NULL) - { - if(!after(left, tmp->lightseg.right)) - { - tmp = TAILQ_PREV(tmp, TQ, ENTRY); - interval_cnt ++; - } - else - { - break; - } - } - tmp = right_tmp; - if(interval_cnt == 0) - { - *segs = NULL; - return 0; - } - *segs = (IVI_seg_t **)malloc(interval_cnt * sizeof(IVI_seg_t *)); - for(i = interval_cnt - 1; i >= 0; i--) - { - (*segs)[i] = (IVI_seg_t *)tmp; - tmp = TAILQ_PREV(tmp, TQ, ENTRY); + max_cnt *= 2; + *segs = (IVI_seg_t **)realloc(*segs, max_cnt * sizeof(IVI_seg_t *)); } + (*segs)[interval_cnt] = tmp_seg; + interval_cnt ++; + tmp_node = rb_next(tmp_node); } return interval_cnt; } @@ -531,129 +596,41 @@ int IVI_query(IVI_t * handler, OFFSET_TYPE left, OFFSET_TYPE right, IVI_seg_t ** **/ int IVI_query_continuous(IVI_t * handler, OFFSET_TYPE left, OFFSET_TYPE right, IVI_seg_t *** segs) { - IVI_shadow_t * shadow_ivi; - IVI_shadow_seg_t *head, *tail, *tmp, *left_tmp, *right_tmp; - int interval_cnt = 0, i; - if(NULL == handler || after(left, right)) { + //augments error return -1; } - shadow_ivi = (IVI_shadow_t *)handler; - head = TAILQ_FIRST(&(shadow_ivi->ivi_queue)); - tail = TAILQ_LAST(&(shadow_ivi->ivi_queue), TQ); + int interval_cnt = 0, max_cnt = 8; + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + struct rb_node * root = shadow_ivi->root.rb_node; + struct rb_node * min_overlap = __min_interval_search_from(root, left, right); + struct rb_node * tmp_node = min_overlap; - - /* Traverse from head or tail? We need to decide */ - if(closer_to_head(head, tail, left)) + *segs = (IVI_seg_t **)malloc(max_cnt * sizeof(IVI_seg_t *)); + while (tmp_node != NULL) { - tmp = head; - while(tmp != NULL) + IVI_seg_t * tmp_seg = (IVI_seg_t *)(rb_entry(tmp_node, IVI_shadow_seg_t, rb)); + if(!__is_overlapped(tmp_seg->left, tmp_seg->right, left, right)) { - if(after(left, tmp->lightseg.right)) - { - tmp = TAILQ_NEXT(tmp, ENTRY); - } - else - { - /* Get the seg which left is in or before*/ - left_tmp = tmp; - break; - } + break; } - if(tmp == NULL) + if(interval_cnt > max_cnt) { - *segs = NULL; - return 0; + max_cnt += 8; + *segs = (IVI_seg_t **)realloc(*segs, max_cnt * sizeof(IVI_seg_t *)); } - - /* Get the num of overlapped segs */ - while(tmp != NULL) + (*segs)[interval_cnt] = tmp_seg; + interval_cnt ++; + tmp_node = rb_next(tmp_node); + IVI_seg_t * prev_tmp_seg = tmp_seg; + tmp_seg = (IVI_seg_t *)(rb_entry(tmp_node, IVI_shadow_seg_t, rb)); + if(!continuous(prev_tmp_seg->right, tmp_seg->left)) { - if(!before(right, tmp->lightseg.left)) - { - tmp = TAILQ_NEXT(tmp, ENTRY); - interval_cnt ++; - } - else - { - break; - } - - IVI_shadow_seg_t * prev = TAILQ_PREV(tmp, TQ, ENTRY); - if(tmp != NULL && !continuous(prev->lightseg.right, tmp->lightseg.left)) - { - break; - } - } - - tmp = left_tmp; - if(interval_cnt == 0) - { - *segs = NULL; - return 0; - } - *segs = (IVI_seg_t **)malloc(interval_cnt * sizeof(IVI_seg_t *)); - for(i = 0; i < interval_cnt; i++) - { - (*segs)[i] = (IVI_seg_t *)tmp; - tmp = TAILQ_NEXT(tmp, ENTRY); + break; } } - else - { - tmp = tail; - while(tmp != NULL) - { - if(before(right, tmp->lightseg.left)) - { - tmp = TAILQ_PREV(tmp, TQ, ENTRY); - } - else - { - right_tmp = tmp; - break; - } - } - if(tmp == NULL) - { - *segs = NULL; - return 0; - } - - /* Get the num of overlapped segs */ - while(tmp != NULL) - { - if(!after(left, tmp->lightseg.right)) - { - tmp = TAILQ_PREV(tmp, TQ, ENTRY); - interval_cnt ++; - } - else - { - break; - } - IVI_shadow_seg_t * next = TAILQ_NEXT(tmp, ENTRY); - if(tmp != NULL && !continuous(tmp->lightseg.right, next->lightseg.left)) - { - break; - } - } - tmp = right_tmp; - if(interval_cnt == 0) - { - *segs = NULL; - return 0; - } - *segs = (IVI_seg_t **)malloc(interval_cnt * sizeof(IVI_seg_t *)); - for(i = interval_cnt - 1; i >= 0; i--) - { - (*segs)[i] = (IVI_seg_t *)tmp; - tmp = TAILQ_PREV(tmp, TQ, ENTRY); - } - } - return interval_cnt; } @@ -698,6 +675,41 @@ OFFSET_TYPE IVI_seg_length(IVI_t * handler) } +/** + * Name: + * IVI_mem_occupy + * Description: + * Get the memory occupy of given interval index handler + * Params: + * handler: The handler of InterVal Index created by IVI_create. + * Return: + * Return the memory occupy of given interval index handler + **/ +unsigned long long IVI_mem_occupy(IVI_t * handler) +{ + if(handler == NULL) + return 0; + IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; + return shadow_ivi->mem_occupy; +} + + +static void __inorder_traverse(struct rb_node * root, IVI_callback_t cb, void * usr_para) +{ + if(root == NULL) + { + return; + } + + /* save first in case of root is freed in callback */ + struct rb_node * left_node = root->rb_left; + struct rb_node * right_node = root->rb_right; + __inorder_traverse(left_node, cb, usr_para); + IVI_seg_t * seg = (IVI_seg_t *)(rb_entry(root, IVI_shadow_seg_t, rb)); + cb(seg, usr_para); + __inorder_traverse(right_node, cb, usr_para); + return; +} /** * Name: @@ -720,17 +732,6 @@ void IVI_traverse(IVI_t * handler, IVI_callback_t cb, void * usr_para) } IVI_shadow_t * shadow_ivi = (IVI_shadow_t *)handler; - IVI_shadow_seg_t * tmp_seg = TAILQ_FIRST(&(shadow_ivi->ivi_queue)); - IVI_shadow_seg_t * tmp; - /* Traverse the IVI */ - while(tmp_seg != NULL) - { - /* - * The place we can't use TAILQ_FOREACH because we - * do not no what will callback funciton does. - * */ - tmp = TAILQ_NEXT(tmp_seg, ENTRY); - cb((IVI_seg_t *)tmp_seg, usr_para); - tmp_seg = tmp; - } + __inorder_traverse(shadow_ivi->root.rb_node, cb, usr_para); + return; } diff --git a/src/inc_internal/interval_index.h b/src/entry/interval_index.h similarity index 92% rename from src/inc_internal/interval_index.h rename to src/entry/interval_index.h index ad2dca4..a67c7ea 100644 --- a/src/inc_internal/interval_index.h +++ b/src/entry/interval_index.h @@ -6,7 +6,7 @@ * (3) The interval supports rollback. * * author: zhengchao@iie.ac.cn tangqi@iie.ac.cn - * last modify time: 2015-08-29 + * last modify time: 2015-12-04 *************************************************************************/ #ifndef _INTERVAL_INDEX_H_ @@ -16,12 +16,11 @@ extern "C"{ #endif -#include "queue.h" #define SIZE_8 #ifdef SIZE_8 -typedef unsigned long long OFFSET_TYPE; +typedef unsigned long long OFFSET_TYPE; typedef signed long long S_OFFSET_TYPE; #else typedef unsigned int OFFSET_TYPE; @@ -61,6 +60,10 @@ static inline int continuous(OFFSET_TYPE prev, OFFSET_TYPE next) } +IVI_seg_t * IVI_first_seg(IVI_t * handler); +IVI_seg_t * IVI_last_seg(IVI_t * handler); +IVI_seg_t * IVI_prev_seg(IVI_seg_t * seg); +IVI_seg_t * IVI_next_seg(IVI_seg_t * seg); IVI_seg_t * IVI_prev_continuous_seg(IVI_seg_t * seg); IVI_seg_t * IVI_next_continuous_seg(IVI_seg_t * seg); @@ -71,22 +74,22 @@ IVI_seg_t * IVI_next_continuous_seg(IVI_seg_t * seg); typedef enum __Relation_t{ LEFT_NO_OVERLAP = 1, // |___A___| // |___B___| - + LEFT_OVERLAP, // |___A___| // |___B___| CONTAINED, // |___A___| // |_____B_____| - + CONTAIN, // |_____A_____| // |___B___| - + RIGHT_OVERLAP, // |___A___| // |___B___| - + RIGHT_NO_OVERLAP, // |___A___| // |___B___| - + ERROR }Relation_t; @@ -273,6 +276,18 @@ int IVI_seg_cnt(IVI_t * handler); OFFSET_TYPE IVI_seg_length(IVI_t * handler); +/** + * Name: + * IVI_mem_occupy + * Description: + * Get the memory occupy of given interval index handler + * Params: + * handler: The handler of InterVal Index created by IVI_create. + * Return: + * Return the memory occupy of given interval index handler + **/ +unsigned long long IVI_mem_occupy(IVI_t * handler); + /** * Name: diff --git a/src/entry/json2iris.cpp b/src/entry/json2iris.cpp index cdf5a98..d515995 100644 --- a/src/entry/json2iris.cpp +++ b/src/entry/json2iris.cpp @@ -89,7 +89,7 @@ int set_iris_descriptor(const char* json_file,cJSON *json,struct iris_descriptio hargs.thread_safe=1; hargs.hash_slot_size = 1024; hargs.max_elem_num = 0; - hargs.eliminate_type = HASH_ELIMINATE_ALGO_LRU; + hargs.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; hargs.expire_time = 0; hargs.key_comp = NULL; hargs.key2index = NULL; @@ -110,8 +110,11 @@ int set_iris_descriptor(const char* json_file,cJSON *json,struct iris_descriptio map_register(iris_cfg->str2int_map, "ip",TABLE_TYPE_IP); map_register(iris_cfg->str2int_map, "string",TABLE_TYPE_EXPR); + map_register(iris_cfg->str2int_map, "expr",TABLE_TYPE_EXPR); + map_register(iris_cfg->str2int_map, "expr_plus",TABLE_TYPE_EXPR_PLUS); map_register(iris_cfg->str2int_map, "intval",TABLE_TYPE_INTVAL); map_register(iris_cfg->str2int_map, "digest",TABLE_TYPE_DIGEST); + map_register(iris_cfg->str2int_map, "ipv4",4); map_register(iris_cfg->str2int_map, "ipv6",6); @@ -364,7 +367,7 @@ int write_ip_rule(cJSON *region_json,struct iris_description_t *p_iris,const cha return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); } -int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) +int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,enum MAAT_TABLE_TYPE table_type,void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -378,6 +381,13 @@ int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const c json_cmd[cmd_cnt].json_type=cJSON_Number; cmd_cnt++; + if(table_type==TABLE_TYPE_EXPR_PLUS) + { + json_cmd[cmd_cnt].json_string="district"; + json_cmd[cmd_cnt].json_type=cJSON_String; + cmd_cnt++; + } + json_cmd[cmd_cnt].json_string="keywords"; json_cmd[cmd_cnt].json_type=cJSON_String; cmd_cnt++; @@ -598,7 +608,8 @@ int write_region_rule(cJSON* region_json,int compile_id,int group_id,iris_descri switch(table_type) { case TABLE_TYPE_EXPR: - ret=write_expr_rule(table_content, p_iris, table_info->table_path, logger); + case TABLE_TYPE_EXPR_PLUS: + ret=write_expr_rule(table_content, p_iris, table_info->table_path,table_type, logger); break; case TABLE_TYPE_IP: ret=write_ip_rule(table_content, p_iris, table_info->table_path, logger); diff --git a/src/entry/map_str2int.cpp b/src/entry/map_str2int.cpp index 07f4b38..2e8752e 100644 --- a/src/entry/map_str2int.cpp +++ b/src/entry/map_str2int.cpp @@ -1,21 +1,35 @@ #include + void map_tmp_free(void* ptr) { free(ptr); } + +long read_map_val(void *data, const uchar *key, uint size, void *user_arg) +{ + if(data!=NULL) + { + *(int*)user_arg=*(int*)data; + return 1; + } + else + { + return 0; + } +} MESA_htable_handle map_create(void) { MESA_htable_handle string2int_map; MESA_htable_create_args_t hargs; memset(&hargs,0,sizeof(hargs)); - hargs.thread_safe=1; - hargs.hash_slot_size = 1024*1024; + hargs.thread_safe=8; + hargs.hash_slot_size = 4*1024; hargs.max_elem_num = 0; - hargs.eliminate_type = HASH_ELIMINATE_ALGO_LRU; + hargs.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; hargs.expire_time = 0; hargs.key_comp = NULL; hargs.key2index = NULL; - hargs.recursive = 0; + hargs.recursive = 1; hargs.data_free = map_tmp_free; hargs.data_expire_with_condition = NULL; string2int_map=MESA_htable_create(&hargs, sizeof(hargs)); @@ -31,20 +45,28 @@ int map_register(MESA_htable_handle handle,const char* string,int value) { unsigned int size=strlen(string); unsigned char *key=(unsigned char *)string; - int *data=(int*)malloc(sizeof(int)); int ret=0; + int * data= (int*)malloc(sizeof(int)); *data=value; ret=MESA_htable_add(handle,key,size,data); + if(ret<0) + { + free(data); + } return ret; } int map_str2int(MESA_htable_handle handle,const char* string,int* value) { int *data=NULL; + long cb_ret=0; unsigned int size=strlen(string); - data=(int*)MESA_htable_search(handle,(unsigned char*)string,size); - if(data!=NULL) + + data=(int*)MESA_htable_search_cb(handle,(unsigned char*)string,size, + read_map_val,value,&cb_ret); + +// data=(int*)MESA_htable_search(handle,(unsigned char*)string,size); + if(cb_ret>0) { - *value=*data; return 1; } else diff --git a/src/entry/mesa_fuzzy.c b/src/entry/mesa_fuzzy.c index 97e332f..88a1b6c 100644 --- a/src/entry/mesa_fuzzy.c +++ b/src/entry/mesa_fuzzy.c @@ -5,151 +5,100 @@ #include #include #include +#include #include "mesa_fuzzy.h" #include "interval_index.h" +//#define DEBUG_PRINT +#define INIT_SIZE 128 +#define ENTROPY_THRESHOLD 0.5 +int count = 0; +const char * b64 = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -#define ROLLING_WINDOW 7 -#define BLOCKSIZE_MIN 3 -#define MAXSIZE 10000 -#define HASH_PRIME 0x01000193 -#define HASH_INIT 0x28021967 - -#define DEBUG (0) - -struct roll_state +struct entry { - unsigned char window[ROLLING_WINDOW]; - unsigned int h1, h2, h3; - unsigned int n; + unsigned int * r_array; + unsigned int r_index; + unsigned int r_size; }; +double get_rs_entropy(unsigned int * r_array, unsigned int r_index); +int cmp(const void * a, const void * b); +void sfh_rs_entropy(IVI_seg_t * seg, void * user_para); +void sfh_tune_simulation(IVI_seg_t * seg, void * user_para); -typedef struct -{ - char * left_data; //ָݵͷָ - unsigned int left_len; //߱ݵij - - char * hash_result; //segmentFNVֵ - unsigned long long left_offset; - unsigned long long right_offset; - - struct roll_state * right_status_r; //ұ߽rollhash״̬ - unsigned int right_status_shash; //ұ߽FNVֵ - unsigned int right_len;//ұ߽ij - int slice_num; - -}fuzzy_node; - - -typedef struct -{ - unsigned long long orilen; - IVI_t * ivi; //ÿһhandle汣һIVIָ룬һIVI汣һļƬ - unsigned long long effective_length; - unsigned long long blocksize; -}fuzzy_handle_inner_t; - - -typedef struct -{ - char * head; //char - unsigned int size; - unsigned int offset; //鳤 - unsigned long long first_FNV_offset; - unsigned long long last_FNV_offset; -}final_result; - - -typedef struct -{ - unsigned long long first_FNV_offset; - unsigned long long last_FNV_offset; - unsigned long long hash_length; -}final_length; - - -unsigned int fuzzy_hash_calculate(IVI_seg_t * seg, const char * data, unsigned long long offset, unsigned long long blocksize); -void fuzzy_calculate_self(IVI_seg_t * seg, const char * data, unsigned long long offset, unsigned long long blocksize); -void fuzzy_calculate_self_with_prev(IVI_seg_t * prev_seg, IVI_seg_t * seg, const char * data, unsigned long long blocksize); -void fuzzy_modify_next(IVI_seg_t * seg, IVI_seg_t * next_seg, unsigned long long blocksize); -unsigned long long get_prev_continous_length(IVI_seg_t * seg); -unsigned int segment_overlap(fuzzy_handle_t * handle, fuzzy_node * fnode, unsigned int size, unsigned long long offset, const char * data); -void fuzzy_hash_merge(IVI_seg_t * seg, void * user_para); -void fuzzy_hash_merge_new(IVI_seg_t * seg, void * user_para); -void fuzzy_hash_length(IVI_seg_t * seg, void * user_para); -unsigned long long fuzzy_status(fuzzy_handle_t * handle, int type); -unsigned long long get_blocksize(unsigned long long orilen); - -char * b64 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - +void write_uint_array(fuzzy_handle_inner_t * handle,unsigned int ** array, unsigned int *index,unsigned int *size,unsigned int value); /** * roll_stateʼ */ -static void roll_init(struct roll_state * self) +static inline void roll_init(struct roll_state_t * self) { - memset(self, 0, sizeof(struct roll_state)); + memset(self, 0, sizeof(struct roll_state_t)); } - /** * roll_hashֵⲿݶȡ */ -static void roll_hash(struct roll_state * self, unsigned char c) +static inline void roll_hash(struct roll_state_t * self, unsigned char c) { - self->h2 -= self->h1; - self->h2 += ROLLING_WINDOW * (unsigned int)c; + self->h2 -= self->h1; + self->h2 += ROLLING_WINDOW * (unsigned int)c; - self->h1 += (unsigned int)c; - self->h1 -= (unsigned int)self->window[self->n]; + self->h1 += (unsigned int)c; + self->h1 -= (unsigned int)self->window[self->n]; - self->window[self->n] = c; - self->n++; - if (self->n == ROLLING_WINDOW) - self->n = 0; - self->h3 <<= 5; - self->h3 ^= c; + self->window[self->n] = c; + self->n++; + if (self->n == ROLLING_WINDOW) + { + self->n = 0; + } + self->h3 <<= 5; + self->h3 ^= c; } - /** * 㴰roll_hashֵÿroll_hashֵһƬ */ -static unsigned int roll_sum(const struct roll_state * self) +static inline unsigned int roll_sum(const struct roll_state_t * self) { - return self->h1 + self->h2 + self->h3; - /* return self->h1 + self->h2; */ + return self->h1 + self->h2 + self->h3; } - /** * ƬFNVֵ */ -static unsigned int sum_hash(unsigned char c, unsigned int h) +static inline unsigned int sum_hash(unsigned char c, unsigned int h) { - return (h * HASH_PRIME) ^ c; + return (h * HASH_PRIME) ^ c; } - /** * handle */ fuzzy_handle_t * fuzzy_create_handle(unsigned long long origin_len) { - fuzzy_handle_inner_t * handle = NULL; - unsigned long long tmp_blksize=get_blocksize(origin_len); - if(tmp_blksize==0) - { - return NULL; - } - handle = (fuzzy_handle_inner_t *)malloc(sizeof(fuzzy_handle_inner_t)); - handle->orilen = origin_len; - handle->ivi = IVI_create(); - handle->effective_length = 0; - handle->blocksize=tmp_blksize; - return (fuzzy_handle_t *)handle; + fuzzy_handle_inner_t * handle = NULL; + unsigned long long tmp_blksize = 0; + tmp_blksize = get_blocksize(origin_len); + + if(tmp_blksize==0) + { + return NULL; + } + handle = (fuzzy_handle_inner_t *)calloc(1,sizeof(fuzzy_handle_inner_t)); + handle->fuzzy_node_memory = 0; + handle->IVI_memory = 0; + handle->fuzzy_node_memory += sizeof(fuzzy_handle_inner_t); + handle->orilen = origin_len; + handle->ivi = IVI_create(); + handle->effective_length = 0; + handle->length_increase = 0; + handle->sim_tuned_rs_cnt = 0; + handle->blocksize=tmp_blksize; + handle->do_tune=0; + return (fuzzy_handle_t *)handle; } @@ -158,678 +107,596 @@ fuzzy_handle_t * fuzzy_create_handle(unsigned long long origin_len) */ void fuzzy_node_free(IVI_seg_t * seg, void * usr_para) { - //printf("free seg[%lu, %lu]\n", seg->left, seg->right); - fuzzy_node * temp = (fuzzy_node*)(seg->data); - if(temp->left_data != NULL) - { - free(temp->left_data); - temp->left_data = NULL; - } - if(temp->hash_result != NULL) - { - free(temp->hash_result); - temp->hash_result = NULL; - } - free(temp->right_status_r); - temp->right_status_r = NULL; - free(temp); - temp = NULL; - return; + fuzzy_handle_inner_t * _handle = (fuzzy_handle_inner_t *)usr_para; + sfh_seg_t * temp = (sfh_seg_t*)(seg->data); + _handle->fuzzy_node_memory-=destroy_sfh_seg(temp); + return; } - -/** - * handle - */ void fuzzy_destroy_handle(fuzzy_handle_t * handle) -{ - IVI_destroy(((fuzzy_handle_inner_t *)handle)->ivi, fuzzy_node_free, NULL); - free((fuzzy_handle_inner_t *)handle); - return; +{ + IVI_destroy(((fuzzy_handle_inner_t *)handle)->ivi, fuzzy_node_free, (void *)handle); + ((fuzzy_handle_inner_t *)handle)->fuzzy_node_memory -= sizeof(fuzzy_handle_inner_t); + free((fuzzy_handle_inner_t *)handle); + return; } - -/** - * ݣҼݵfuzzy_hashֵ - */ unsigned int fuzzy_feed(fuzzy_handle_t * handle, const char * data, unsigned int size, unsigned long long offset) { + fuzzy_handle_inner_t * _handle=(fuzzy_handle_inner_t *)handle; if(data == NULL || size == 0) { return 0; } - fuzzy_node * node = (fuzzy_node *)calloc(sizeof(fuzzy_node), 1); - node->right_status_r = (struct roll_state *)calloc(sizeof (struct roll_state), 1); - roll_init(node->right_status_r); - node->slice_num = 0; - unsigned int length = segment_overlap(handle, node, size, offset, data); - if(offset == 0) + unsigned int length = segment_overlap(_handle, size, offset, data); + _handle->effective_length += length; + _handle->length_increase += length; + if(_handle->s_state_cnt>EXPECT_SIGNATURE_LEN&&_handle->do_tune==1) { - ((fuzzy_handle_inner_t *)handle)->effective_length += size - node->right_len; - return (size - node->right_len); + + + unsigned long long check_length = (_handle->effective_length/_handle->s_state_cnt)*EXPECT_SIGNATURE_LEN; + + if(_handle->length_increase > check_length) + { + + + IVI_traverse(_handle->ivi, sfh_tune_simulation, (void *)_handle); + if(_handle->sim_tuned_rs_cnt>EXPECT_SIGNATURE_LEN) + { + _handle->blocksize*=2; + IVI_traverse(_handle->ivi, sfh_tune_seg, (void *)_handle); + } + _handle->sim_tuned_rs_cnt = 0; + _handle->length_increase = 0; + } } - else - { - ((fuzzy_handle_inner_t *)handle)->effective_length += length; - } - return length; //ѾЧ +#if 0 + fuzzy_digest(handle,result, sizeof(result)); + printf("%llu %s\n",offset,result); +#endif + return length; } +void sfh_tune_simulation(IVI_seg_t * seg, void * user_para) +{ + sfh_seg_t * tmp = (sfh_seg_t *)(seg->data); + int i = 0; + fuzzy_handle_inner_t * _handle = (fuzzy_handle_inner_t *)user_para; + unsigned long long blocksize = _handle->blocksize * 2; + for(i = 0; i < tmp->r_cnt; i++) + { + if(tmp->r_array[i] % blocksize == blocksize -1) + { + _handle->sim_tuned_rs_cnt ++; + } + } +} + unsigned long long get_blocksize(unsigned long long orilen) { - double tmp = orilen/(64 * BLOCKSIZE_MIN); - double index = floor(log(tmp)/log(2)); - double tmp_t = pow(2, index); - unsigned long long blocksize = (unsigned long long)(tmp_t * BLOCKSIZE_MIN); - return blocksize; + double tmp = orilen/(64 * BLOCKSIZE_MIN); + double index = floor(log(tmp)/log(2)); + double tmp_t = pow(2, index); + unsigned long long blocksize = (unsigned long long)(tmp_t * BLOCKSIZE_MIN); + if(blocksize == 0) + { + blocksize = BLOCKSIZE_MIN; + } + return blocksize; +// return BLOCKSIZE_MIN; } +sfh_seg_t* create_sfh_seg(fuzzy_handle_inner_t * _handle) +{ + sfh_seg_t*p=calloc(sizeof(sfh_seg_t),1); + roll_init(&(p->r_state)); + p->s_size = INIT_SIZE; + p->r_size = INIT_SIZE; + p->r_array = (unsigned int*)malloc(sizeof(unsigned int)*(p->r_size)); + p->s_array = (struct zt_state_t*)malloc(sizeof(struct zt_state_t)*(p->s_size)); + zt_hash_initial(&(p->s_state)); + zt_hash_initial(&(p->ps)); + _handle->fuzzy_node_memory += sizeof(sfh_seg_t) + sizeof(unsigned int)*(p->r_size) + sizeof(struct zt_state_t)*(p->s_size); + return p; +} +//return freed memory size +int destroy_sfh_seg(sfh_seg_t*p) +{ + int ret_size=0; + //printf("before free p->s_array:\n"); + if(p->s_array != NULL) + { + //printf("p->s_array is not NULL\n"); + free(p->s_array); + p->s_array=NULL; + ret_size+=p->s_size*sizeof(struct zt_state_t); + } + //printf("after free p->s_array\n"); + if(p->r_array != NULL) + { + free(p->r_array); + p->r_array=NULL; + ret_size+=p->r_size*sizeof(unsigned int); + } + //printf("after free p->r_array\n"); + ret_size+=sizeof(sfh_seg_t); + //printf("before free p\n"); + free(p); + p=NULL; + //printf("after free p\n"); + return ret_size; +} /** * жǷѾи */ -unsigned int segment_overlap(fuzzy_handle_t * handle, fuzzy_node * fnode, unsigned int size, unsigned long long offset, const char * data) +unsigned int segment_overlap(fuzzy_handle_inner_t * _handle, unsigned int size, unsigned long long offset, const char * data) { IVI_seg_t ** overlap_segs = NULL; - IVI_seg_t * seg = IVI_seg_malloc(offset, offset + size -1, (void *)fnode); - int overlap_segnum = 0; + IVI_seg_t *new_seg=NULL,*target_seg=NULL; + sfh_seg_t* sfh_seg=NULL; + int overlap_segnum = 0,i=0,co_seg_num=0,ret=0; unsigned int effective_length = 0; - unsigned int total_length = 0; - unsigned long long blocksize = ((fuzzy_handle_inner_t *)handle)->blocksize; + unsigned long long calc_begin=offset; + unsigned long long calc_end=offset+size-1; + + //printf("size: %u\n",size); + //printf("before query\n"); + /*ѯǷиǣиǣظǵsegmentƬûиǣ0*/ + if(offset>0) + { + overlap_segnum = IVI_query(_handle->ivi, offset-1, offset + size, &overlap_segs); + } + else + { + overlap_segnum = IVI_query(_handle->ivi, 0, offset + size, &overlap_segs); + } + IVI_seg_t * co_overlap_segs[overlap_segnum+1]; + assert(overlap_segnum>=0); - /*ѯǷиǣиǣظǵsegmentƬûиǣ0*/ - overlap_segnum = IVI_query(((fuzzy_handle_inner_t *)handle)->ivi, offset, offset + size - 1, &overlap_segs); - - /*ֵΪ˵IJ⣬ӡϢ*/ - if(overlap_segnum < 0) - { - printf("fragment info error!\n"); - IVI_seg_free(seg, fuzzy_node_free, NULL); - return 0; - } - - /*ֵΪ0˵ûиǵֱӲ*/ - if(overlap_segnum == 0) - { - IVI_insert(((fuzzy_handle_inner_t *)handle)->ivi,seg); - effective_length = fuzzy_hash_calculate(seg, data, offset, blocksize); - - total_length = seg->right - seg->left + 1; - return effective_length; - } - - /*ֵΪǵƬҪݸһһд*/ - int flag = 0; - int i; - for(i = 0; i < overlap_segnum; i++) - { - switch(IVI_relative_position(seg, overlap_segs[i])) - { - case LEFT_OVERLAP: //󸲸ǣsegֵΪoverlap_segֵ - { - seg->right = overlap_segs[i]->left - 1; - break; - } - case CONTAIN: //ϵDzֱӲ룬Ȼısegֵdataƶָλ - { - if(overlap_segs[i]->left >= 1 && overlap_segs[i]->left - 1 >= seg->left) - { - fuzzy_node * node = (fuzzy_node *)calloc(sizeof(fuzzy_node), 1); - memcpy(node, fnode, sizeof(fuzzy_node)); - node->right_status_r = (struct roll_state *)calloc(sizeof (struct roll_state), 1); - roll_init(node->right_status_r); - IVI_seg_t * thseg = IVI_seg_malloc(seg->left, overlap_segs[i]->left - 1, (void *)node); - IVI_insert(((fuzzy_handle_inner_t *)handle)->ivi,thseg); - effective_length += fuzzy_hash_calculate(thseg, data, offset, blocksize); - total_length += thseg->right - thseg->left + 1; - } - seg->left = overlap_segs[i]->right + 1; - data = data + ((seg->left) - offset); - offset = seg->left; - break; - } - case RIGHT_OVERLAP: //ҸǣsegֵΪoverlap_segֵ - { - seg->left = overlap_segs[i]->right + 1; - data = data + ((seg->left) - offset); - offset = seg->left; - break; - } - case CONTAINED: //ֱƬ - { - flag = 1; - //printf("contained! free seg\n"); - IVI_seg_free(seg, fuzzy_node_free, NULL); - free(overlap_segs); - break; - } - default: - break; - } - if(flag == 1) - { - return 0; - } - - } - - /*µݲ뵽棬ҽм*/ - if(seg->left <= seg->right) - { - IVI_insert(((fuzzy_handle_inner_t *)handle)->ivi, seg); - effective_length += fuzzy_hash_calculate(seg, data, offset, blocksize); - total_length += seg->right - seg->left + 1; - //((fuzzy_handle_inner_t *)handle)->effective_length += effective_length; - } - else - { - IVI_seg_free(seg, fuzzy_node_free, NULL); - } - - free(overlap_segs); - return effective_length; + if(overlap_segnum==0||offsetleft) + { + sfh_seg=create_sfh_seg(_handle); + calc_begin=offset; + if(overlap_segnum == 0) + { + calc_end=offset+size-1; + } + else + { + calc_end=MIN(overlap_segs[0]->left-1,offset+size-1); + } + new_seg = IVI_seg_malloc(calc_begin, calc_end, (void *)sfh_seg); + _handle->s_state_cnt+=sfh_update_seg(_handle, sfh_seg,data+calc_begin-offset, calc_end-calc_begin+1, _handle->blocksize); + effective_length+=(calc_end-calc_begin+1); + co_overlap_segs[co_seg_num]=new_seg; + co_seg_num++; + } + for(i=0;iivi,overlap_segs[i]); + _handle->IVI_memory = IVI_mem_occupy(_handle->ivi); + assert(ret==0); + } + for(i=0;iright+1,calc_begin); + if(i+1left-1,offset+size-1); + } + else + { + calc_end=offset+size-1; + } + if(!after(calc_begin,calc_end)) + { + sfh_seg=(sfh_seg_t*)(co_overlap_segs[i]->data); + _handle->s_state_cnt+=sfh_update_seg(_handle,sfh_seg,data+calc_begin-offset, calc_end-calc_begin+1, _handle->blocksize); + effective_length+=(calc_end-calc_begin+1); + co_overlap_segs[i]->right+=calc_end-calc_begin+1; + calc_begin=calc_end+1; + } + } + target_seg=co_overlap_segs[0]; + for(i=0;idata)->r_index>0&&((sfh_seg_t*)co_overlap_segs[i]->data)->r_index>0) + { + memset(&result_p,0,sizeof(result_p)); + result_p.data=rp_buff; + result_p.size=sizeof(rp_buff); + sfh_output_state(target_seg,&result_p); + memset(&result_n,0,sizeof(result_n)); + result_n.data=rn_buff; + result_n.size=sizeof(rn_buff); + sfh_output_state(co_overlap_segs[i],&result_n); + printf("%s[%llu:%llu] %s[%llu:%llu]\n",rp_buff,target_seg->left, + target_seg->right, + rn_buff,co_overlap_segs[i]->left, + co_overlap_segs[i]->right); + } +#endif + _handle->s_state_cnt+=sfh_merge_seg(_handle,(sfh_seg_t*)target_seg->data, (sfh_seg_t*)co_overlap_segs[i]->data, _handle->blocksize); + target_seg->right=co_overlap_segs[i]->right; + IVI_seg_free(co_overlap_segs[i], fuzzy_node_free, (void *)_handle); + } + //IVI_seg_t * insert_seg=NULL; + //insert_seg = IVI_seg_malloc(target_seg->left, target_seg->right, target_seg->data); + ret=IVI_insert(_handle->ivi,target_seg); + _handle->IVI_memory = IVI_mem_occupy(_handle->ivi); + assert(ret==0); + free(overlap_segs); + return effective_length; } - -/** - * ǰƬfuzzy_hashֵ - */ -unsigned int fuzzy_hash_calculate(IVI_seg_t * seg, const char * data, unsigned long long offset, unsigned long long blocksize) +int cmp(const void * a, const void * b) { - IVI_seg_t * prev_seg; - IVI_seg_t * next_seg; - unsigned int effective_length = 0; - - prev_seg = IVI_prev_continuous_seg(seg); - next_seg = IVI_next_continuous_seg(seg); - //printf("seg->right = %lu, seg->left = %lu\n", seg->right, seg->left); - unsigned int size = seg->right - seg->left + 1; - fuzzy_node * node = (fuzzy_node *)(seg->data); - if(NULL == prev_seg) - { - //ǰƬֱӳʼroll_stateм - roll_init(node->right_status_r); - fuzzy_calculate_self(seg, data, offset, blocksize); - effective_length = size - node->left_len; - node->left_offset = offset + node->left_len; - } - else - { - //ǰƬȡǰƬұ߽м״ֵ̬м - - fuzzy_calculate_self_with_prev(prev_seg, seg, data, blocksize); - effective_length = size + ((fuzzy_node *)(prev_seg->data))->right_len; - node->left_offset = offset - ((fuzzy_node *)(prev_seg->data))->right_len; - } - - /* кƬ,ԼĽҪƬ,޸ĺķƬ */ - if(next_seg != NULL) - { - //ںƬƬұ߽м״ֵ̬ȡͺƬ߽м״̬м - fuzzy_modify_next(seg, next_seg, blocksize); - - effective_length += ((fuzzy_node *)(next_seg->data))->left_len; - node->right_offset = offset + size + ((fuzzy_node *)(next_seg->data))->left_len; - - } - else - { - effective_length -= node->right_len; - node->right_offset = offset + (size - (node->right_len)); - } - return effective_length; + unsigned int tmp_a = *(unsigned int *)a; + unsigned int tmp_b = *(unsigned int *)b; + if(before(tmp_a, tmp_b)) + { + return -1; + } + else if(after(tmp_a, tmp_b)) + { + return 1; + } + else + { + return 0; + } } - - -void fuzzy_calculate_self(IVI_seg_t * seg, const char * data, unsigned long long offset, unsigned long long blocksize) +double get_rs_entropy(unsigned int * r_array, unsigned int r_index) { - fuzzy_node * node = (fuzzy_node *)(seg->data); - struct roll_state * rs = node->right_status_r; - unsigned long long size = seg->right - seg->left + 1; - unsigned int FNV_hash_value = HASH_INIT; + qsort(r_array, r_index, sizeof(unsigned int), cmp); + unsigned int current_r = r_array[0]; + unsigned int * tmp_r = r_array; + unsigned int count = 0; + double sum = 0; + int i = 0; + for(i = 0; i <= r_index; i++) + { + if(i == r_index || *tmp_r != current_r) + { + double p = (double)count/r_index; + //printf("count : %d\n",count); + //printf("r_index: %u\n",r_index); + //printf("p:%f\n",p); + if(p != 0) + { + sum += p * (log(p)/log(2)); + } + current_r = *tmp_r; + count = 0; + } + else + { + count++; + } + if(i < r_index) + { + tmp_r ++; + } + } + return (-sum); - char * FNV_hash = (char *)malloc(sizeof(char)*size); - unsigned long long fnv_index = 0, i=0, last_slice_index=0; - unsigned int roll_hash_value; - for(i = 0; i < size; i++) - { - roll_hash(rs, data[i]); - roll_hash_value = roll_sum(rs); - FNV_hash_value = sum_hash(data[i], FNV_hash_value); - if(i >= ROLLING_WINDOW - 1 && roll_hash_value % blocksize == blocksize - 1) - { - node->slice_num ++; - - if(node->slice_num == 1) - { - node->left_len = i + 1; - } - last_slice_index = i; - /* FNVֵ */ - FNV_hash[fnv_index ++] = b64[FNV_hash_value % 64]; - //printf("data[%lu]=%c, FNV_hash = %c\n", i, data[i], b64[FNV_hash_value % 64]); - FNV_hash_value = HASH_INIT; - } - } - - /* һƬûҵ */ - if(node->slice_num == 0) - { - node->left_len = size; - node->right_len = 0; - } - else - { - node->right_len = size - last_slice_index - 1; - } - node->right_status_shash = FNV_hash_value; - - /* ƽhash_result */ - node->hash_result = (char *)malloc(sizeof(char) * (fnv_index + 1)); - memcpy(node->hash_result, FNV_hash, fnv_index); - (node->hash_result)[fnv_index] = '\0'; - - node->left_data = (char *)malloc(sizeof(char) * (node->left_len)); - memcpy(node->left_data, data, node->left_len); - - free(FNV_hash); - return; } - -unsigned long long get_prev_continous_length(IVI_seg_t * seg) +/*void sfh_rs_entropy(IVI_seg_t * seg, void * user_para) { - unsigned long long length = 0; - IVI_seg_t * temp = seg; - while(temp != NULL) - { - length += temp->right - temp->left + 1; - if(length >= ROLLING_WINDOW) - return length; - temp = IVI_prev_continuous_seg(temp); - } - return length; + sfh_seg_t * tmp = (sfh_seg_t *)(seg->data); + int i = 0; + for(i = 0; i < tmp->r_cnt; i++) + { + write_uint_array((unsigned int**)(&(((struct entry *)user_para)->r_array)), &(((struct entry *)user_para)->r_index), + &(((struct entry *)user_para)->r_size), tmp->r_array[i]); + } +}*/ + + + +void sfh_tune_seg(IVI_seg_t * seg, void * user_para) +{ + int i = 0, j = 0; + sfh_seg_t * p = (sfh_seg_t *)(seg->data); + if(p->r_cnt== 0) + { + return; + } + + fuzzy_handle_inner_t * _handle = (fuzzy_handle_inner_t *)user_para; + unsigned long long blocksize = _handle->blocksize; + + struct zt_state_t tmp_zt; + int new_zt_cnt=0; + zt_hash_initial(&tmp_zt); + _handle->s_state_cnt -= p->s_cnt; + + for(j = 0; j < p->r_cnt; j++) + { + if(j == 0) + { + zt_hash_arymul(&tmp_zt, &(p->ps)); + } + else + { + zt_hash_arymul(&tmp_zt, &(p->s_array[j - 1])); + } +// if((p->r_array[j] &(blocksize-1)) == blocksize - 1) + if(p->r_array[j] % blocksize == blocksize - 1) + { + p->r_array[i]=p->r_array[j]; + i++; + if(i>1) + { + p->s_array[new_zt_cnt].val=tmp_zt.val; + new_zt_cnt++; + } + else + { + p->ps.val=tmp_zt.val; + } + zt_hash_initial(&tmp_zt); + } + } + zt_hash_arymul(&tmp_zt, &(p->s_state)); + if(i == 0) + { + zt_hash_initial(&(p->ps)); + } + p->s_state.val = tmp_zt.val; + p->s_cnt = new_zt_cnt; + p->r_cnt = i; + _handle->s_state_cnt += p->s_cnt; + assert(p->r_cnt>=p->s_cnt); + + //printf("after state_cnt:%d,block:%llu\n",_handle->s_state_cnt,_handle->blocksize); } -/** - * ǰεı - */ -void fuzzy_calculate_self_with_prev(IVI_seg_t * prev_seg, IVI_seg_t * seg, const char * data, unsigned long long blocksize) +void write_uint_array(fuzzy_handle_inner_t *_handle,unsigned int ** array,unsigned int *index, unsigned int *size,unsigned int value) { - fuzzy_node * prev_node = (fuzzy_node *)(prev_seg->data); - fuzzy_node * node = (fuzzy_node *)(seg->data); - - /* ʹǰεroll state */ - memcpy(node->right_status_r, prev_node->right_status_r, sizeof(struct roll_state)); - struct roll_state * rs = node->right_status_r; - unsigned long long size = seg->right - seg->left + 1; - unsigned int FNV_hash_value = prev_node->right_status_shash; - - - char * FNV_hash = (char *)malloc(sizeof(char)*size); - unsigned long long fnv_index = 0, i=0, last_slice_index=0; - unsigned int roll_hash_value; - unsigned long long prev_len = get_prev_continous_length(prev_seg); - - for(i = 0; i < size; i++) - { - roll_hash(rs, data[i]); - roll_hash_value = roll_sum(rs); - FNV_hash_value = sum_hash(data[i], FNV_hash_value); - if(i + prev_len >= ROLLING_WINDOW \ - && roll_hash_value % blocksize == blocksize - 1) - { - node->slice_num ++; - if(node->slice_num == 1) - { - node->left_len = i + 1; - } - - last_slice_index = i; - /* FNVֵ */ - FNV_hash[fnv_index ++] = b64[FNV_hash_value % 64]; - //printf("data[%lu]=%c, FNV_hash = %c\n", i, data[i], b64[FNV_hash_value % 64]); - FNV_hash_value = HASH_INIT; - } - } - - /* һƬûҵ */ - if(node->slice_num == 0) - { - node->left_len = size; - node->right_len = 0; - } - else - { - node->right_len = size - last_slice_index - 1; - } - node->right_status_shash = FNV_hash_value; - - /* ƽhash_result */ - node->hash_result = (char *)malloc(sizeof(char) * (fnv_index + 1)); - memcpy(node->hash_result, FNV_hash, fnv_index); - (node->hash_result)[fnv_index] = '\0'; - - node->left_data = (char *)malloc(sizeof(char) * (node->left_len)); - memcpy(node->left_data, data, node->left_len); - - free(FNV_hash); + if(*index==*size) + { + (*size)*=2; + *array=(unsigned int*)realloc(*array,sizeof(unsigned int)*(*size)); + _handle->fuzzy_node_memory += (*size)/2; + } + (*array)[*index]=value; + (*index)++; + return; } - - -void fuzzy_modify_self_with_prev(IVI_seg_t * prev_seg, IVI_seg_t * seg, char * data, unsigned long long blocksize) +int sfh_update_seg(fuzzy_handle_inner_t * _handle, sfh_seg_t * p, const char * data, unsigned long data_size,unsigned long long blocksize) { - fuzzy_node * prev_node = (fuzzy_node *)(prev_seg->data); - fuzzy_node * node = (fuzzy_node *)(seg->data); - - /* ʹǰεroll state */ - memcpy(node->right_status_r, prev_node->right_status_r, sizeof(struct roll_state)); - struct roll_state * rs = node->right_status_r; - unsigned long long size = seg->right - seg->left + 1; - unsigned int FNV_hash_value = prev_node->right_status_shash; - - - char * FNV_hash = (char *)malloc(sizeof(char)*size); - unsigned long long fnv_index = 0, i=0, last_slice_index=0; - unsigned int roll_hash_value; - unsigned long long prev_len = get_prev_continous_length(prev_seg); - for(i = 0; i < size; i++) - { - roll_hash(rs, data[i]); - roll_hash_value = roll_sum(rs); - FNV_hash_value = sum_hash(data[i], FNV_hash_value); - if(i + prev_len >= ROLLING_WINDOW \ - && roll_hash_value % blocksize == blocksize- 1) - { - node->slice_num ++; - if(node->slice_num == 1) - { - node->left_len = i + 1; - } - - last_slice_index = i; - /* FNVֵ */ - FNV_hash[fnv_index ++] = b64[FNV_hash_value % 64]; - //printf("data[%lu]=%c, FNV_hash = %c\n", i, data[i], b64[FNV_hash_value % 64]); - FNV_hash_value = HASH_INIT; - } - } - - /* һƬûҵ */ - if(node->slice_num == 0) - { - node->left_len = size; - node->right_len = 0; - } - else - { - node->right_len = size - last_slice_index - 1; - } - node->right_status_shash = FNV_hash_value; - - /* ƽhash_result */ - free(node->hash_result); - node->hash_result = (char *)malloc(sizeof(char) * (fnv_index + 1)); - memcpy(node->hash_result, FNV_hash, fnv_index); - (node->hash_result)[fnv_index] = '\0'; - - //printf("old node->left_data = %s\n", node->left_data); - free(node->left_data); - node->left_data = (char *)malloc(sizeof(char) * (node->left_len)); - memcpy(node->left_data, data, node->left_len); - //printf("new node->left_data = %s\n", node->left_data); - free(FNV_hash); -} - - - -/** - * εı - */ -void fuzzy_modify_next(IVI_seg_t * seg, IVI_seg_t * next_seg, unsigned long long blocksize) -{ - IVI_seg_t * tmp_curr_seg = seg; - IVI_seg_t * tmp_next_seg = next_seg; - while(tmp_next_seg != NULL) - { - fuzzy_node * tmp_next_node = (fuzzy_node *)(tmp_next_seg->data); - if(tmp_next_node->slice_num != 0) - { - break; - } - - /* һûзƬ, ¼ */ + unsigned long i = 0; + unsigned int roll_hash_value = 0; + int state_inc_cnt=0; + if(p->msize < ROLLING_WINDOW - 1) + { + for(i = 0; i < ROLLING_WINDOW - p->msize && i < data_size; i++) + { + p->mbuf[p->msize + i] = data[i]; + roll_hash(&(p->r_state), data[i]); + } + p->msize += i; + } + for(; i < data_size; i++) + { + roll_hash(&(p->r_state), data[i]); + roll_hash_value = roll_sum(&(p->r_state)); - char * data = (char *)malloc(sizeof(char) * (tmp_next_node->left_len)); - memcpy(data, tmp_next_node->left_data, tmp_next_node->left_len); - fuzzy_modify_self_with_prev(tmp_curr_seg, tmp_next_seg, data, blocksize); - free(data); - - tmp_curr_seg = tmp_next_seg; - tmp_next_seg = IVI_next_continuous_seg(tmp_next_seg); - } - - unsigned long long prev_len = get_prev_continous_length(tmp_curr_seg); - /* tmp_next_segзƬ */ - if(tmp_next_seg != NULL) - { - fuzzy_node * tmp_curr_node = (fuzzy_node *)(tmp_curr_seg->data); - fuzzy_node * tmp_next_node = (fuzzy_node *)(tmp_next_seg->data); - - unsigned long long size = tmp_next_node->left_len; - - char * FNV_hash = (char *)malloc(sizeof(char)*size); - unsigned long long fnv_index = 0, i; - unsigned int roll_hash_value; - - struct roll_state rs; - memcpy(&rs, tmp_curr_node->right_status_r, sizeof(struct roll_state)); - char * data = tmp_next_node->left_data; - unsigned int FNV_hash_value = tmp_curr_node->right_status_shash; - for(i = 0; i < size; i++) - { - roll_hash(&rs, data[i]); - roll_hash_value = roll_sum(&rs); - FNV_hash_value = sum_hash(data[i], FNV_hash_value); - - if((i + prev_len >= ROLLING_WINDOW) \ - && roll_hash_value % blocksize == blocksize - 1) - { - tmp_next_node->slice_num ++; - FNV_hash[fnv_index ++] = b64[FNV_hash_value % 64]; - //printf("data[%lu]=%c, FNV_hash = %c\n", i, data[i], b64[FNV_hash_value % 64]); - FNV_hash_value = HASH_INIT; - - if(fnv_index == 1) - { - tmp_next_node->left_len = i + 1; - } - } - } - - tmp_next_node->slice_num --; - - - /* ƽhash_result */ - unsigned long long old_len = strlen(tmp_next_node->hash_result); - if(old_len == 1) - { - free(tmp_next_node->hash_result); - tmp_next_node->hash_result = (char *)malloc(sizeof(char) * (fnv_index + 1)); - memcpy(tmp_next_node->hash_result, FNV_hash, fnv_index); - (tmp_next_node->hash_result)[fnv_index] = '\0'; - } - else - { - unsigned long long new_len = old_len - 1 + fnv_index; - char tmp[old_len - 1]; - char * old_hash = (tmp_next_node->hash_result) + 1; - memcpy(tmp, old_hash, old_len - 1); - free(tmp_next_node->hash_result); - tmp_next_node->hash_result = (char *)malloc(sizeof(char) * (new_len + 1)); - memset(tmp_next_node->hash_result, '\0', (new_len + 1)); - memcpy(tmp_next_node->hash_result, FNV_hash, fnv_index); - strncat(tmp_next_node->hash_result, tmp, old_len - 1); - (tmp_next_node->hash_result)[new_len] = '\0'; - } - free(FNV_hash); - } - return; + zt_hash(&(p->s_state),data[i]); +// if((roll_hash_value & (blocksize-1)) == blocksize - 1) + if((roll_hash_value % (blocksize)) == blocksize - 1) + { + p->slice_num ++; + if(p->r_cnt==0) + { + p->ps.val=p->s_state.val; + } + else + { +#ifdef DEBUG_PRINT + printf("p->s_cnt:%u\n",p->s_cnt); + printf("p->s_size:%u\n",p->s_size); +#endif + write_uint_array(_handle,(unsigned int**)(&(p->s_array)), &(p->s_cnt),&(p->s_size),p->s_state.val); + state_inc_cnt++; + } +#ifdef DEBUG_PRINT + printf("p->r_cnt:%u\n",p->s_cnt); + printf("p->r_size:%u\n",p->s_size); +#endif + write_uint_array(_handle,&(p->r_array),&(p->r_cnt),&(p->r_size),roll_hash_value); + zt_hash_initial(&(p->s_state)); + } + } + assert(p->r_cnt>=p->s_cnt); + p->right_offset+=data_size; + return state_inc_cnt; } +int sfh_merge_seg(fuzzy_handle_inner_t * _handle, sfh_seg_t * p, sfh_seg_t * n,unsigned long long blocksize) +{ + unsigned int roll_hash_value = 0; + int i = 0,state_inc_cnt=0; + struct roll_state_t * rs = &(p->r_state); + for(i = 0; i < n->msize; i++) + { + roll_hash(rs, n->mbuf[i]); + roll_hash_value = roll_sum(rs); + zt_hash(&(p->s_state), n->mbuf[i]); +// if((roll_hash_value & (blocksize-1)) == blocksize - 1) + if(roll_hash_value % blocksize == blocksize - 1) + { + //printf("roll_value : %u\n",roll_hash_value); + p->slice_num ++; +// unsigned int * tmp = (unsigned int *)(p->s_array); + if(p->r_cnt == 0) + { + p->ps.val = p->s_state.val; + } + else + { + write_uint_array(_handle,(unsigned int **)(&(p->s_array)), &(p->s_cnt), &(p->s_size), p->s_state.val); + state_inc_cnt++; + } + write_uint_array(_handle,&(p->r_array),&(p->r_cnt), &(p->r_size), roll_hash_value); + zt_hash_initial(&(p->s_state)); + } + } + if(n->r_cnt==0) + { + zt_hash_arymul(&(p->s_state),&(n->ps)); + zt_hash_arymul(&(p->s_state), &(n->s_state)); + } + else + { + if(p->r_cnt==0) + { + zt_hash_arymul(&(p->s_state),&(n->ps)); + p->ps.val=p->s_state.val; + } + else + { + zt_hash_arymul(&(p->s_state), &(n->ps)); + write_uint_array(_handle,(unsigned int **)(&(p->s_array)), &(p->s_cnt), &(p->s_size), p->s_state.val); + state_inc_cnt++; + } + p->s_state.val=n->s_state.val; + } + for(i=0;ir_cnt;i++) + { + write_uint_array(_handle,&(p->r_array),&(p->r_cnt), &(p->r_size), n->r_array[i]); + } + for(i=0;is_cnt;i++) + { + write_uint_array(_handle, (unsigned int **)(&(p->s_array)), &(p->s_cnt), &(p->s_size), n->s_array[i].val); + } + memcpy(&(p->r_state),&(n->r_state),sizeof(p->r_state)); + assert(p->r_cnt>=p->s_cnt); + + return state_inc_cnt; +} /** * ȡhash_resultֵƴӣγresultabc[1:100]def[200:300]ָʽ */ int fuzzy_digest(fuzzy_handle_t * handle, char * result, unsigned int size) { - final_result * temp = (final_result *)malloc(sizeof(final_result)); - temp->head = result; - temp->size = size; - temp->offset = 0; - temp->first_FNV_offset = 0; - temp->last_FNV_offset = 0; - //final_result * temp = (final_result *)malloc(sizeof(final_result)); - //temp->offset = 0; - IVI_traverse(((fuzzy_handle_inner_t *)handle)->ivi, fuzzy_hash_merge_new, (void *) temp); - result[size - 1] = '\0'; - //memcpy(result, temp->result, size); - free(temp); - return 0; + final_result * temp = (final_result *)malloc(sizeof(final_result)); + fuzzy_handle_inner_t* _handle=(fuzzy_handle_inner_t *)handle; + temp->data = result; + temp->size = size-1; + temp->offset = 0; + temp->first_ZTH_offset = 0; + temp->last_ZTH_offset = 0; + temp->offset+=snprintf(temp->data,temp->size,"%llu:",_handle->blocksize); + IVI_traverse(_handle->ivi, sfh_output_state, (void *) temp); + result[temp->offset] = '\0'; + free(temp); + temp = NULL; + return 0; } - -void fuzzy_hash_merge_new(IVI_seg_t * seg, void * user_para) +void sfh_output_state(IVI_seg_t * seg, void * user_para) { - IVI_seg_t * prev_seg; - IVI_seg_t * next_seg; - prev_seg = IVI_prev_continuous_seg(seg); - next_seg = IVI_next_continuous_seg(seg); - char buffer[MAXSIZE]; - final_result * tmp = (final_result *)user_para; - fuzzy_node * node = (fuzzy_node *)(seg->data); - if(node->slice_num != 0) - { - tmp->last_FNV_offset = seg->right - node->right_len; - } - - if(prev_seg == NULL && next_seg == NULL) //ǰƬͺƬΪգƴ - { - tmp->first_FNV_offset = seg->left; - tmp->last_FNV_offset = seg->right - node->right_len; - sprintf(buffer, "%s[%llu:%llu]", node->hash_result, tmp->first_FNV_offset, seg->right); - } - if(prev_seg == NULL && next_seg != NULL) //ǰƬΪգƬΪգֵFNVֵȥ - { - tmp->first_FNV_offset = seg->left; - - sprintf(buffer, "%s", node->hash_result); - } - if(prev_seg != NULL && next_seg == NULL) //ǰƬΪգƬΪգֵƫ - { - - sprintf(buffer, "%s[%llu:%llu]", node->hash_result, tmp->first_FNV_offset, seg->right); - } - if(prev_seg != NULL && next_seg != NULL) //ǰƬΪգƬΪգFNVֵȥ - { - sprintf(buffer, "%s", node->hash_result); - } - - unsigned int inner_size = strlen(buffer); - tmp->offset += inner_size; - if(tmp->offset <= tmp->size) - { - memcpy(tmp->head, buffer, inner_size); - tmp->head += inner_size; - } - else - { - unsigned int length = (tmp->size - (tmp->offset - inner_size)); - if(length != 0) - { - memcpy(tmp->head, buffer, length); - } - tmp->offset = tmp->size; - tmp->head += length; - } - return; + char buffer[2000]; + final_result * result = (final_result *)user_para; + sfh_seg_t * node = (sfh_seg_t *)(seg->data); + char hash_result[node->r_cnt + 1]; + hash_result[node->r_cnt] = '\0'; + int i = 0, j = 0, to_copy_len=0,this_len=0; + if(node->s_cnt==0&&!(seg->left==0&&node->s_cnt>0)) + { + return; + } + memset(hash_result,0,sizeof(hash_result)); + if(seg->left == 0) + { + hash_result[j] = b64[zt_hash_code(&(node->ps)) & 0x3F]; + j++; + } + for(i = 0; i < node->s_cnt; i++,j++) + { + hash_result[j] = b64[(node->s_array[i].val) & 0x3F]; + } + hash_result[j+1]='\0'; + if(0!=memcmp(&(node->s_state),ZT_INIT_VAL,sizeof(ZT_INIT_VAL))) + { + result->last_char=b64[zt_hash_code(&(node->s_state)) & 0x3F]; + } + else + { + result->last_char='\0'; + } + hash_result[j+1] = '\0'; + this_len=snprintf(buffer,sizeof(buffer), "[%llu:%llu]",seg->left, seg->right); + this_len+=j; +// this_len++; + to_copy_len=MIN(this_len,result->size-result->offset); + memcpy(result->data+result->offset,hash_result,j); + result->offset+=j; + memcpy(result->data+result->offset,buffer,to_copy_len-j); + result->offset += to_copy_len-j; + return; } - /** * fuzzy_hashĸֳ */ unsigned long long fuzzy_status(fuzzy_handle_t * handle, int type) { unsigned long long length; - final_length tmp_length; fuzzy_handle_inner_t * _handle = (fuzzy_handle_inner_t *)(handle); + final_length tmp_length; + char buffer[64]; switch(type) { - case TOTAL_LENGTH: //Ѿhashֵȫ - length = IVI_seg_length(_handle->ivi); - break; + case TOTAL_LENGTH: //Ѿhashֵȫ + length = IVI_seg_length(_handle->ivi); + break; case EFFECTIVE_LENGTH: //ڼhashֵЧ - length = _handle->effective_length; - break; + length = _handle->effective_length; + break; case HASH_LENGTH: //ϣij - tmp_length.hash_length = 0; - tmp_length.first_FNV_offset = 0; - tmp_length.last_FNV_offset = 0; - IVI_traverse(_handle->ivi, fuzzy_hash_length, (void *)&tmp_length); - length = tmp_length.hash_length + 1; - break; + tmp_length.hash_length = 0; + tmp_length.first_ZTH_offset = 0; + tmp_length.last_ZTH_offset = 0; + tmp_length.hash_length+=snprintf(buffer,sizeof(buffer),"%llu:",_handle->blocksize); + IVI_traverse(_handle->ivi, fuzzy_hash_length, (void *)&tmp_length); + length = tmp_length.hash_length + 1; + break; + case MEMORY_OCCUPY: + length = _handle->fuzzy_node_memory + _handle->IVI_memory; + break; default: - return 0; + return 0; } return length; } - void fuzzy_hash_length(IVI_seg_t * seg, void * user_para) { + char buffer[100]; + final_length * tmp = (final_length *)user_para; + sfh_seg_t * node = (sfh_seg_t *)(seg->data); - IVI_seg_t * prev_seg; - IVI_seg_t * next_seg; - prev_seg = IVI_prev_continuous_seg(seg); - next_seg = IVI_next_continuous_seg(seg); - char buffer[MAXSIZE]; - final_length * tmp = (final_length *)user_para; - fuzzy_node * node = (fuzzy_node *)(seg->data); - if(node->slice_num != 0) - { - //printf("node->slice_num != 0\n"); - tmp->last_FNV_offset = seg->right - node->right_len; - //printf("%lu\n", tmp->last_FNV_offset); - } - - if(prev_seg == NULL && next_seg == NULL) //ǰƬͺƬΪգƴ - { - tmp->first_FNV_offset = seg->left; - tmp->last_FNV_offset = seg->right - node->right_len; - sprintf(buffer, "%s[%llu:%llu]", node->hash_result, tmp->first_FNV_offset, seg->right); - } - if(prev_seg == NULL && next_seg != NULL) //ǰƬΪգƬΪգֵFNVֵȥ - { - tmp->first_FNV_offset = seg->left; - - sprintf(buffer, "%s", node->hash_result); - } - if(prev_seg != NULL && next_seg == NULL) //ǰƬΪգƬΪգֵƫ - { - - sprintf(buffer, "%s[%llu:%llu]", node->hash_result, tmp->first_FNV_offset, seg->right); - } - if(prev_seg != NULL && next_seg != NULL) //ǰƬΪգƬΪգFNVֵȥ - { - sprintf(buffer, "%s", node->hash_result); - } - tmp->hash_length += strlen(buffer); - return; + sprintf(buffer, "[%llu:%llu]", seg->left, seg->right); + + tmp->hash_length += node->r_cnt*sizeof(char) + strlen(buffer); + return; } diff --git a/src/entry/rbtree.c b/src/entry/rbtree.c new file mode 100644 index 0000000..4c68ad1 --- /dev/null +++ b/src/entry/rbtree.c @@ -0,0 +1,548 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + (C) 2002 David Woodhouse + (C) 2012 Michel Lespinasse + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/lib/rbtree.c +*/ + +#include "rbtree.h" +#include "rbtree_augmented.h" +/* + * red-black trees properties: http://en.wikipedia.org/wiki/Rbtree + * + * 1) A node is either red or black + * 2) The root is black + * 3) All leaves (NULL) are black + * 4) Both children of every red node are black + * 5) Every simple path from root to leaves contains the same number + * of black nodes. + * + * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two + * consecutive red nodes in a path and every red node is therefore followed by + * a black. So if B is the number of black nodes on every simple path (as per + * 5), then the longest possible path due to 4 is 2B. + * + * We shall indicate color with case, where black nodes are uppercase and red + * nodes will be lowercase. Unknown color nodes shall be drawn as red within + * parentheses and have some accompanying text comment. + */ + +static inline void rb_set_black(struct rb_node *rb) +{ + rb->__rb_parent_color |= RB_BLACK; +} + +static inline struct rb_node *rb_red_parent(struct rb_node *red) +{ + return (struct rb_node *)red->__rb_parent_color; +} + +/* + * Helper function for rotations: + * - old's parent and color get assigned to new + * - old gets assigned new as a parent and 'color' as a color. + */ +static inline void +__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, + struct rb_root *root, int color) +{ + struct rb_node *parent = rb_parent(old); + new->__rb_parent_color = old->__rb_parent_color; + rb_set_parent_color(old, new, color); + __rb_change_child(old, new, parent, root); +} + +static __always_inline void +__rb_insert(struct rb_node *node, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) +{ + struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; + + while (1) { + /* + * Loop invariant: node is red + * + * If there is a black parent, we are done. + * Otherwise, take some corrective action as we don't + * want a red root or two consecutive red nodes. + */ + if (!parent) { + rb_set_parent_color(node, NULL, RB_BLACK); + break; + } else if (rb_is_black(parent)) + break; + + gparent = rb_red_parent(parent); + + tmp = gparent->rb_right; + if (parent != tmp) { /* parent == gparent->rb_left */ + if (tmp && rb_is_red(tmp)) { + /* + * Case 1 - color flips + * + * G g + * / \ / \ + * p u --> P U + * / / + * n n + * + * However, since g's parent might be red, and + * 4) does not allow this, we need to recurse + * at g. + */ + rb_set_parent_color(tmp, gparent, RB_BLACK); + rb_set_parent_color(parent, gparent, RB_BLACK); + node = gparent; + parent = rb_parent(node); + rb_set_parent_color(node, parent, RB_RED); + continue; + } + + tmp = parent->rb_right; + if (node == tmp) { + /* + * Case 2 - left rotate at parent + * + * G G + * / \ / \ + * p U --> n U + * \ / + * n p + * + * This still leaves us in violation of 4), the + * continuation into Case 3 will fix that. + */ + parent->rb_right = tmp = node->rb_left; + node->rb_left = parent; + if (tmp) + rb_set_parent_color(tmp, parent, + RB_BLACK); + rb_set_parent_color(parent, node, RB_RED); + augment_rotate(parent, node); + parent = node; + tmp = node->rb_right; + } + + /* + * Case 3 - right rotate at gparent + * + * G P + * / \ / \ + * p U --> n g + * / \ + * n U + */ + gparent->rb_left = tmp; /* == parent->rb_right */ + parent->rb_right = gparent; + if (tmp) + rb_set_parent_color(tmp, gparent, RB_BLACK); + __rb_rotate_set_parents(gparent, parent, root, RB_RED); + augment_rotate(gparent, parent); + break; + } else { + tmp = gparent->rb_left; + if (tmp && rb_is_red(tmp)) { + /* Case 1 - color flips */ + rb_set_parent_color(tmp, gparent, RB_BLACK); + rb_set_parent_color(parent, gparent, RB_BLACK); + node = gparent; + parent = rb_parent(node); + rb_set_parent_color(node, parent, RB_RED); + continue; + } + + tmp = parent->rb_left; + if (node == tmp) { + /* Case 2 - right rotate at parent */ + parent->rb_left = tmp = node->rb_right; + node->rb_right = parent; + if (tmp) + rb_set_parent_color(tmp, parent, + RB_BLACK); + rb_set_parent_color(parent, node, RB_RED); + augment_rotate(parent, node); + parent = node; + tmp = node->rb_left; + } + + /* Case 3 - left rotate at gparent */ + gparent->rb_right = tmp; /* == parent->rb_left */ + parent->rb_left = gparent; + if (tmp) + rb_set_parent_color(tmp, gparent, RB_BLACK); + __rb_rotate_set_parents(gparent, parent, root, RB_RED); + augment_rotate(gparent, parent); + break; + } + } +} + +/* + * Inline version for rb_erase() use - we want to be able to inline + * and eliminate the dummy_rotate callback there + */ +static __always_inline void +____rb_erase_color(struct rb_node *parent, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) +{ + struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; + + while (1) { + /* + * Loop invariants: + * - node is black (or NULL on first iteration) + * - node is not the root (parent is not NULL) + * - All leaf paths going through parent and node have a + * black node count that is 1 lower than other leaf paths. + */ + sibling = parent->rb_right; + if (node != sibling) { /* node == parent->rb_left */ + if (rb_is_red(sibling)) { + /* + * Case 1 - left rotate at parent + * + * P S + * / \ / \ + * N s --> p Sr + * / \ / \ + * Sl Sr N Sl + */ + parent->rb_right = tmp1 = sibling->rb_left; + sibling->rb_left = parent; + rb_set_parent_color(tmp1, parent, RB_BLACK); + __rb_rotate_set_parents(parent, sibling, root, + RB_RED); + augment_rotate(parent, sibling); + sibling = tmp1; + } + tmp1 = sibling->rb_right; + if (!tmp1 || rb_is_black(tmp1)) { + tmp2 = sibling->rb_left; + if (!tmp2 || rb_is_black(tmp2)) { + /* + * Case 2 - sibling color flip + * (p could be either color here) + * + * (p) (p) + * / \ / \ + * N S --> N s + * / \ / \ + * Sl Sr Sl Sr + * + * This leaves us violating 5) which + * can be fixed by flipping p to black + * if it was red, or by recursing at p. + * p is red when coming from Case 1. + */ + rb_set_parent_color(sibling, parent, + RB_RED); + if (rb_is_red(parent)) + rb_set_black(parent); + else { + node = parent; + parent = rb_parent(node); + if (parent) + continue; + } + break; + } + /* + * Case 3 - right rotate at sibling + * (p could be either color here) + * + * (p) (p) + * / \ / \ + * N S --> N Sl + * / \ \ + * sl Sr s + * \ + * Sr + */ + sibling->rb_left = tmp1 = tmp2->rb_right; + tmp2->rb_right = sibling; + parent->rb_right = tmp2; + if (tmp1) + rb_set_parent_color(tmp1, sibling, + RB_BLACK); + augment_rotate(sibling, tmp2); + tmp1 = sibling; + sibling = tmp2; + } + /* + * Case 4 - left rotate at parent + color flips + * (p and sl could be either color here. + * After rotation, p becomes black, s acquires + * p's color, and sl keeps its color) + * + * (p) (s) + * / \ / \ + * N S --> P Sr + * / \ / \ + * (sl) sr N (sl) + */ + parent->rb_right = tmp2 = sibling->rb_left; + sibling->rb_left = parent; + rb_set_parent_color(tmp1, sibling, RB_BLACK); + if (tmp2) + rb_set_parent(tmp2, parent); + __rb_rotate_set_parents(parent, sibling, root, + RB_BLACK); + augment_rotate(parent, sibling); + break; + } else { + sibling = parent->rb_left; + if (rb_is_red(sibling)) { + /* Case 1 - right rotate at parent */ + parent->rb_left = tmp1 = sibling->rb_right; + sibling->rb_right = parent; + rb_set_parent_color(tmp1, parent, RB_BLACK); + __rb_rotate_set_parents(parent, sibling, root, + RB_RED); + augment_rotate(parent, sibling); + sibling = tmp1; + } + tmp1 = sibling->rb_left; + if (!tmp1 || rb_is_black(tmp1)) { + tmp2 = sibling->rb_right; + if (!tmp2 || rb_is_black(tmp2)) { + /* Case 2 - sibling color flip */ + rb_set_parent_color(sibling, parent, + RB_RED); + if (rb_is_red(parent)) + rb_set_black(parent); + else { + node = parent; + parent = rb_parent(node); + if (parent) + continue; + } + break; + } + /* Case 3 - right rotate at sibling */ + sibling->rb_right = tmp1 = tmp2->rb_left; + tmp2->rb_left = sibling; + parent->rb_left = tmp2; + if (tmp1) + rb_set_parent_color(tmp1, sibling, + RB_BLACK); + augment_rotate(sibling, tmp2); + tmp1 = sibling; + sibling = tmp2; + } + /* Case 4 - left rotate at parent + color flips */ + parent->rb_left = tmp2 = sibling->rb_right; + sibling->rb_right = parent; + rb_set_parent_color(tmp1, sibling, RB_BLACK); + if (tmp2) + rb_set_parent(tmp2, parent); + __rb_rotate_set_parents(parent, sibling, root, + RB_BLACK); + augment_rotate(parent, sibling); + break; + } + } +} + +/* Non-inline version for rb_erase_augmented() use */ +void __rb_erase_color(struct rb_node *parent, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) +{ + ____rb_erase_color(parent, root, augment_rotate); +} + +/* + * Non-augmented rbtree manipulation functions. + * + * We use dummy augmented callbacks here, and have the compiler optimize them + * out of the rb_insert_color() and rb_erase() function definitions. + */ + +static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {} +static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {} +static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {} + +static const struct rb_augment_callbacks dummy_callbacks = { + dummy_propagate, dummy_copy, dummy_rotate +}; + +void rb_insert_color(struct rb_node *node, struct rb_root *root) +{ + __rb_insert(node, root, dummy_rotate); +} + +void rb_erase(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *rebalance; + rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); + if (rebalance) + ____rb_erase_color(rebalance, root, dummy_rotate); +} + +/* + * Augmented rbtree manipulation functions. + * + * This instantiates the same __always_inline functions as in the non-augmented + * case, but this time with user-defined callbacks. + */ + +void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) +{ + __rb_insert(node, root, augment_rotate); +} + +/* + * This function returns the first node (in sort order) of the tree. + */ +struct rb_node *rb_first(const struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_left) + n = n->rb_left; + return n; +} + +struct rb_node *rb_last(const struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_right) + n = n->rb_right; + return n; +} + +struct rb_node *rb_next(const struct rb_node *node) +{ + struct rb_node *parent; + + if (RB_EMPTY_NODE(node)) + return NULL; + + /* + * If we have a right-hand child, go down and then left as far + * as we can. + */ + if (node->rb_right) { + node = node->rb_right; + while (node->rb_left) + node=node->rb_left; + return (struct rb_node *)node; + } + + /* + * No right-hand children. Everything down and left is smaller than us, + * so any 'next' node must be in the general direction of our parent. + * Go up the tree; any time the ancestor is a right-hand child of its + * parent, keep going up. First time it's a left-hand child of its + * parent, said parent is our 'next' node. + */ + while ((parent = rb_parent(node)) && node == parent->rb_right) + node = parent; + + return parent; +} + +struct rb_node *rb_prev(const struct rb_node *node) +{ + struct rb_node *parent; + + if (RB_EMPTY_NODE(node)) + return NULL; + + /* + * If we have a left-hand child, go down and then right as far + * as we can. + */ + if (node->rb_left) { + node = node->rb_left; + while (node->rb_right) + node=node->rb_right; + return (struct rb_node *)node; + } + + /* + * No left-hand children. Go up till we find an ancestor which + * is a right-hand child of its parent. + */ + while ((parent = rb_parent(node)) && node == parent->rb_left) + node = parent; + + return parent; +} + +void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root) +{ + struct rb_node *parent = rb_parent(victim); + + /* Set the surrounding nodes to point to the replacement */ + __rb_change_child(victim, new, parent, root); + if (victim->rb_left) + rb_set_parent(victim->rb_left, new); + if (victim->rb_right) + rb_set_parent(victim->rb_right, new); + + /* Copy the pointers/colour from the victim to the replacement */ + *new = *victim; +} + +static struct rb_node *rb_left_deepest_node(const struct rb_node *node) +{ + for (;;) { + if (node->rb_left) + node = node->rb_left; + else if (node->rb_right) + node = node->rb_right; + else + return (struct rb_node *)node; + } +} + +struct rb_node *rb_next_postorder(const struct rb_node *node) +{ + const struct rb_node *parent; + if (!node) + return NULL; + parent = rb_parent(node); + + /* If we're sitting on node, we've already seen our children */ + if (parent && node == parent->rb_left && parent->rb_right) { + /* If we are the parent's left node, go to the parent's right + * node then all the way down to the left */ + return rb_left_deepest_node(parent->rb_right); + } else + /* Otherwise we are the parent's right node, and the parent + * should be next */ + return (struct rb_node *)parent; +} + +struct rb_node *rb_first_postorder(const struct rb_root *root) +{ + if (!root->rb_node) + return NULL; + + return rb_left_deepest_node(root->rb_node); +} diff --git a/src/entry/rbtree.h b/src/entry/rbtree.h new file mode 100644 index 0000000..adfad02 --- /dev/null +++ b/src/entry/rbtree.h @@ -0,0 +1,118 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/include/linux/rbtree.h + + To use rbtrees you'll have to implement your own insert and search cores. + This will avoid us to use callbacks and to drop drammatically performances. + I know it's not the cleaner way, but in C (not in C++) to get + performances and genericity... + + See Documentation/rbtree.txt for documentation and samples. +*/ + +#ifndef _LINUX_RBTREE_H +#define _LINUX_RBTREE_H + +#include + +struct rb_node { + unsigned long __rb_parent_color; + struct rb_node *rb_right; + struct rb_node *rb_left; +} __attribute__((aligned(sizeof(long)))); + /* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct rb_root { + struct rb_node *rb_node; +}; + + +#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) + +#define RB_ROOT (struct rb_root) { NULL, } + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type, member) );}) +#endif + +#define rb_entry(ptr, type, member) container_of(ptr, type, member) + +#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) + +/* 'empty' nodes are nodes that are known not to be inserted in an rbtree */ +#define RB_EMPTY_NODE(node) \ + ((node)->__rb_parent_color == (unsigned long)(node)) +#define RB_CLEAR_NODE(node) \ + ((node)->__rb_parent_color = (unsigned long)(node)) + + +extern void rb_insert_color(struct rb_node *, struct rb_root *); +extern void rb_erase(struct rb_node *, struct rb_root *); + + +/* Find logical next and previous nodes in a tree */ +extern struct rb_node *rb_next(const struct rb_node *); +extern struct rb_node *rb_prev(const struct rb_node *); +extern struct rb_node *rb_first(const struct rb_root *); +extern struct rb_node *rb_last(const struct rb_root *); + +/* Postorder iteration - always visit the parent after its children */ +extern struct rb_node *rb_first_postorder(const struct rb_root *); +extern struct rb_node *rb_next_postorder(const struct rb_node *); + +/* Fast replacement of a single node without remove/rebalance/add/rebalance */ +extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root); + +static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, + struct rb_node ** rb_link) +{ + node->__rb_parent_color = (unsigned long)parent; + node->rb_left = node->rb_right = NULL; + + *rb_link = node; +} + +#define rb_entry_safe(ptr, type, member) \ + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? rb_entry(____ptr, type, member) : NULL; \ + }) + +/** + * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of + * given type safe against removal of rb_node entry + * + * @pos: the 'type *' to use as a loop cursor. + * @n: another 'type *' to use as temporary storage + * @root: 'rb_root *' of the rbtree. + * @field: the name of the rb_node field within 'type'. + */ +#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \ + for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \ + pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \ + typeof(*pos), field); 1; }); \ + pos = n) + +#endif /* _LINUX_RBTREE_H */ diff --git a/src/entry/rbtree_augmented.h b/src/entry/rbtree_augmented.h new file mode 100644 index 0000000..bf3b639 --- /dev/null +++ b/src/entry/rbtree_augmented.h @@ -0,0 +1,241 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + (C) 2002 David Woodhouse + (C) 2012 Michel Lespinasse + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/include/linux/rbtree_augmented.h +*/ + +#ifndef _LINUX_RBTREE_AUGMENTED_H +#define _LINUX_RBTREE_AUGMENTED_H + +#include "rbtree.h" + +/* + * Please note - only struct rb_augment_callbacks and the prototypes for + * rb_insert_augmented() and rb_erase_augmented() are intended to be public. + * The rest are implementation details you are not expected to depend on. + * + * See Documentation/rbtree.txt for documentation and samples. + */ + +struct rb_augment_callbacks { + void (*propagate)(struct rb_node *node, struct rb_node *stop); + void (*copy)(struct rb_node *old, struct rb_node *new); + void (*rotate)(struct rb_node *old, struct rb_node *new); +}; + +extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); +/* + * Fixup the rbtree and update the augmented information when rebalancing. + * + * On insertion, the user must update the augmented information on the path + * leading to the inserted node, then call rb_link_node() as usual and + * rb_augment_inserted() instead of the usual rb_insert_color() call. + * If rb_augment_inserted() rebalances the rbtree, it will callback into + * a user provided function to update the augmented information on the + * affected subtrees. + */ +static inline void +rb_insert_augmented(struct rb_node *node, struct rb_root *root, + const struct rb_augment_callbacks *augment) +{ + __rb_insert_augmented(node, root, augment->rotate); +} + +#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ + rbtype, rbaugmented, rbcompute) \ +static inline void \ +rbname ## _propagate(struct rb_node *rb, struct rb_node *stop) \ +{ \ + while (rb != stop) { \ + rbstruct *node = rb_entry(rb, rbstruct, rbfield); \ + rbtype augmented = rbcompute(node); \ + if (node->rbaugmented == augmented) \ + break; \ + node->rbaugmented = augmented; \ + rb = rb_parent(&node->rbfield); \ + } \ +} \ +static inline void \ +rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ +{ \ + rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ + rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ + new->rbaugmented = old->rbaugmented; \ +} \ +static void \ +rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ +{ \ + rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ + rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ + new->rbaugmented = old->rbaugmented; \ + old->rbaugmented = rbcompute(old); \ +} \ +rbstatic const struct rb_augment_callbacks rbname = { \ + rbname ## _propagate, rbname ## _copy, rbname ## _rotate \ +}; + + +#define RB_RED 0 +#define RB_BLACK 1 + +#define __rb_parent(pc) ((struct rb_node *)(pc & ~3)) + +#define __rb_color(pc) ((pc) & 1) +#define __rb_is_black(pc) __rb_color(pc) +#define __rb_is_red(pc) (!__rb_color(pc)) +#define rb_color(rb) __rb_color((rb)->__rb_parent_color) +#define rb_is_red(rb) __rb_is_red((rb)->__rb_parent_color) +#define rb_is_black(rb) __rb_is_black((rb)->__rb_parent_color) + +static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) +{ + rb->__rb_parent_color = rb_color(rb) | (unsigned long)p; +} + +static inline void rb_set_parent_color(struct rb_node *rb, + struct rb_node *p, int color) +{ + rb->__rb_parent_color = (unsigned long)p | color; +} + +static inline void +__rb_change_child(struct rb_node *old, struct rb_node *new, + struct rb_node *parent, struct rb_root *root) +{ + if (parent) { + if (parent->rb_left == old) + parent->rb_left = new; + else + parent->rb_right = new; + } else + root->rb_node = new; +} + +extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); + +static __always_inline struct rb_node * +__rb_erase_augmented(struct rb_node *node, struct rb_root *root, + const struct rb_augment_callbacks *augment) +{ + struct rb_node *child = node->rb_right, *tmp = node->rb_left; + struct rb_node *parent, *rebalance; + unsigned long pc; + + if (!tmp) { + /* + * Case 1: node to erase has no more than 1 child (easy!) + * + * Note that if there is one child it must be red due to 5) + * and node must be black due to 4). We adjust colors locally + * so as to bypass __rb_erase_color() later on. + */ + pc = node->__rb_parent_color; + parent = __rb_parent(pc); + __rb_change_child(node, child, parent, root); + if (child) { + child->__rb_parent_color = pc; + rebalance = NULL; + } else + rebalance = __rb_is_black(pc) ? parent : NULL; + tmp = parent; + } else if (!child) { + /* Still case 1, but this time the child is node->rb_left */ + tmp->__rb_parent_color = pc = node->__rb_parent_color; + parent = __rb_parent(pc); + __rb_change_child(node, tmp, parent, root); + rebalance = NULL; + tmp = parent; + } else { + struct rb_node *successor = child, *child2; + tmp = child->rb_left; + if (!tmp) { + /* + * Case 2: node's successor is its right child + * + * (n) (s) + * / \ / \ + * (x) (s) -> (x) (c) + * \ + * (c) + */ + parent = successor; + child2 = successor->rb_right; + augment->copy(node, successor); + } else { + /* + * Case 3: node's successor is leftmost under + * node's right child subtree + * + * (n) (s) + * / \ / \ + * (x) (y) -> (x) (y) + * / / + * (p) (p) + * / / + * (s) (c) + * \ + * (c) + */ + do { + parent = successor; + successor = tmp; + tmp = tmp->rb_left; + } while (tmp); + parent->rb_left = child2 = successor->rb_right; + successor->rb_right = child; + rb_set_parent(child, successor); + augment->copy(node, successor); + augment->propagate(parent, successor); + } + + successor->rb_left = tmp = node->rb_left; + rb_set_parent(tmp, successor); + + pc = node->__rb_parent_color; + tmp = __rb_parent(pc); + __rb_change_child(node, successor, tmp, root); + if (child2) { + successor->__rb_parent_color = pc; + rb_set_parent_color(child2, parent, RB_BLACK); + rebalance = NULL; + } else { + unsigned long pc2 = successor->__rb_parent_color; + successor->__rb_parent_color = pc; + rebalance = __rb_is_black(pc2) ? parent : NULL; + } + tmp = successor; + } + + augment->propagate(tmp, NULL); + return rebalance; +} + +static __always_inline void +rb_erase_augmented(struct rb_node *node, struct rb_root *root, + const struct rb_augment_callbacks *augment) +{ + struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); + if (rebalance) + __rb_erase_color(rebalance, root, augment->rotate); +} + +#endif /* _LINUX_RBTREE_AUGMENTED_H */ diff --git a/src/entry/sfh_internal.h b/src/entry/sfh_internal.h new file mode 100644 index 0000000..ddfeddc --- /dev/null +++ b/src/entry/sfh_internal.h @@ -0,0 +1,106 @@ +#include +#include +#include + +#ifndef __SFH_INTERNAL_H_INCLUDE_ +#define __SFH_INTERNAL_H_INCLUDE_ + +#define ROLLING_WINDOW 7 +#define BLOCKSIZE_MIN 3 +#define HASH_PRIME 0x01000193 +#define HASH_INIT 0x28021967 +#define CALCULATE 0 +#define MODIFY 1 +#define EXPECT_SIGNATURE_LEN 64 +#define MEMORY_OCCUPY 3 + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#define DEBUG (0) + +int hash_length; +//int count = 0; +struct roll_state_t +{ + unsigned char window[ROLLING_WINDOW]; + unsigned char pad[1]; + unsigned int h1, h2, h3; + unsigned int n; +}; + + +typedef struct +{ + char mbuf[ROLLING_WINDOW-1]; + char pad[8-ROLLING_WINDOW+1]; + int slice_num; + unsigned int msize; + struct zt_state_t ps; //partial strong hash value + struct zt_state_t s_state;//strong hash state + unsigned long long left_offset; + unsigned long long right_offset; + struct roll_state_t r_state; + unsigned int * r_array; //array to store rolling hash value + unsigned int r_cnt; + unsigned int r_size; + struct zt_state_t * s_array; //array to store strong(Tillichi-Zemor) hash value + unsigned int s_cnt; //always point to the next available position + unsigned int s_size; +}sfh_seg_t; + + +typedef struct +{ + unsigned long long orilen; + IVI_t * ivi; //ÿһhandle汣һIVIָ룬һIVI汣һļƬ + unsigned long long effective_length; + unsigned long long blocksize; + unsigned long long fuzzy_node_memory; + unsigned long long IVI_memory; + unsigned long long length_increase; + int s_state_cnt; + unsigned int sim_tuned_rs_cnt;//rolling state count after a tune simulation + int do_tune; +}fuzzy_handle_inner_t; + + +typedef struct +{ + char * data; //char + unsigned int size; + unsigned int offset; //鳤 + unsigned long long first_ZTH_offset; + unsigned long long last_ZTH_offset; + char last_char; +}final_result; + + +typedef struct +{ + unsigned long long first_ZTH_offset; + unsigned long long last_ZTH_offset; + unsigned long long hash_length; +}final_length; + +sfh_seg_t* create_sfh_seg(fuzzy_handle_inner_t * _handle); +int destroy_sfh_seg(sfh_seg_t*p); +unsigned long long get_blocksize(unsigned long long orilen); +int sfh_merge_seg(fuzzy_handle_inner_t * _handle,sfh_seg_t * seg, sfh_seg_t * next_seg, unsigned long long blocksize); +int sfh_update_seg(fuzzy_handle_inner_t * _handle,sfh_seg_t * p, const char * data, unsigned long data_size, unsigned long long blocksize); +unsigned int segment_overlap(fuzzy_handle_inner_t * handle, unsigned int size, unsigned long long offset, const char * data); +void sfh_tune_seg(IVI_seg_t * seg, void * user_para); +void sfh_output_state(IVI_seg_t * seg, void * user_para); +void fuzzy_hash_length(IVI_seg_t * seg, void * user_para); +unsigned long long fuzzy_status(fuzzy_handle_t * handle, int type); +#endif diff --git a/src/entry/zt_hash.h b/src/entry/zt_hash.h new file mode 100644 index 0000000..8acf0be --- /dev/null +++ b/src/entry/zt_hash.h @@ -0,0 +1,234 @@ +#include +#include + +struct zt_state_t +{ + union + { + unsigned char matrix[4]; //strong hash state + unsigned int val; + }; +}; + +const unsigned char table[256][4] = +{ + {76,28,128,81},{76,204,128,209},{204,128,209,81},{204,76,209,128},{238,209,196,115},{238,63,196,183},{63,209,183,115},{63,238,183,196},{230,196,193,123},{230,34,193,186},{34,196,186,123},{34,230,186,193},{0,183,175,76},{0,183,175,227},{183,183,227,76},{183,0,227,175},{228,193,192,121},{228,37,192,185},{37,193,185,121},{37,228,185,192},{18,186,164,75},{18,168,164,239},{168,186,239,75},{168,18,239,164},{15,175,169,67},{15,160,169,234},{160,175,234,67},{160,15,234,169},{151,227,247,108},{151,116,247,155},{116,227,155,108},{116,151,155,247},{228,192,193,121},{228,36,193,184},{36,192,184,121},{36,228,184,193},{22,185,167,74},{22,175,167,237},{175,185,237,74},{175,22,237,167},{30,164,162,71},{30,186,162,229},{186,164,229,71},{186,30,229,162},{136,239,250,107},{136,103,250,145},{103,239,145,107},{103,136,145,250},{12,169,169,64},{12,165,169,233},{165,169,233,64},{165,12,233,169},{138,234,251,105},{138,96,251,146},{96,234,146,105},{96,138,146,251},{159,247,243,100},{159,104,243,151},{104,247,151,100},{104,159,151,243},{71,155,133,95},{71,220,133,218},{220,155,218,95},{220,71,218,133},{230,193,196,123},{230,39,196,191},{39,193,191,123},{39,230,191,196},{20,184,160,73},{20,172,160,233},{172,184,233,73},{172,20,233,160},{25,167,167,69},{25,190,167,226},{190,167,226,69},{190,25,226,167},{141,237,253,104},{141,96,253,149},{96,237,149,104},{96,141,149,253},{30,162,164,71},{30,188,164,227},{188,162,227,71},{188,30,227,164},{144,229,240,109},{144,117,240,157},{117,229,157,109},{117,144,157,240},{130,250,251,97},{130,120,251,154},{120,250,154,97},{120,130,154,251},{84,145,137,88},{84,197,137,209},{197,145,209,88},{197,84,209,137},{15,169,175,67},{15,166,175,236},{166,169,236,67},{166,15,236,175},{143,233,253,106},{143,102,253,151},{102,233,151,106},{102,143,151,253},{130,251,250,97},{130,121,250,155},{121,251,155,97},{121,130,155,250},{80,146,138,89},{80,194,138,211},{194,146,211,89},{194,80,211,138},{159,243,247,100},{159,108,247,147},{108,243,147,100},{108,159,147,247},{87,151,137,91},{87,192,137,210},{192,151,210,91},{192,87,210,137},{72,133,133,80},{72,205,133,213},{205,133,213,80},{205,72,213,133},{246,218,207,117},{246,44,207,186},{44,218,186,117},{44,246,186,207},{238,196,209,115},{238,42,209,162},{42,196,162,115},{42,238,162,209},{24,191,191,68},{24,167,191,251},{167,191,251,68},{167,24,251,191},{20,160,184,73},{20,180,184,241},{180,160,241,73},{180,20,241,184},{134,233,236,99},{134,111,236,143},{111,233,143,99},{111,134,143,236},{22,167,185,74},{22,177,185,243},{177,167,243,74},{177,22,243,185},{156,226,227,103},{156,126,227,132},{126,226,132,103},{126,156,132,227},{143,253,233,106},{143,114,233,131},{114,253,131,106},{114,143,131,233},{95,149,147,87},{95,202,147,196},{202,149,196,87},{202,95,196,147},{18,164,186,75},{18,182,186,241},{182,164,241,75},{182,18,241,186},{156,227,226,103},{156,127,226,133},{127,227,133,103},{127,156,133,226},{144,240,229,109},{144,96,229,136},{96,240,136,109},{96,144,136,229},{74,157,155,82},{74,215,155,201},{215,157,201,82},{215,74,201,155},{138,251,234,105},{138,113,234,131},{113,251,131,105},{113,138,131,234},{72,154,154,81},{72,210,154,203},{210,154,203,81},{210,72,203,154},{87,137,151,91},{87,222,151,204},{222,137,204,91},{222,87,204,151},{231,209,213,122},{231,54,213,175},{54,209,175,122},{54,231,175,213},{0,175,183,76},{0,175,183,251},{175,175,251,76},{175,0,251,183},{134,236,233,99},{134,106,233,138},{106,236,138,99},{106,134,138,233},{141,253,237,104},{141,112,237,133},{112,253,133,104},{112,141,133,237},{89,151,151,85},{89,206,151,194},{206,151,194,85},{206,89,194,151},{136,250,239,107},{136,114,239,132},{114,250,132,107},{114,136,132,239},{74,155,157,82},{74,209,157,207},{209,155,207,82},{209,74,207,157},{80,138,146,89},{80,218,146,203},{218,138,203,89},{218,80,203,146},{226,211,210,121},{226,49,210,171},{49,211,171,121},{49,226,171,210},{151,247,227,108},{151,96,227,143},{96,247,143,108},{96,151,143,227},{95,147,149,87},{95,204,149,194},{204,147,194,87},{204,95,194,149},{84,137,145,88},{84,221,145,201},{221,137,201,88},{221,84,201,145},{226,210,211,121},{226,48,211,170},{48,210,170,121},{48,226,170,211},{71,133,155,95},{71,194,155,196},{194,133,196,95},{194,71,196,155},{231,213,209,122},{231,50,209,171},{50,213,171,122},{50,231,171,209},{246,207,218,117},{246,57,218,175},{57,207,175,117},{57,246,175,218},{28,186,186,69},{28,166,186,255},{166,186,255,69},{166,28,255,186} +}; + +const static unsigned char galois_mult_8_table[65536] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,29,31,25,27,21,23,17,19,13,15,9,11,5,7,1,3,61,63,57,59,53,55,49,51,45,47,41,43,37,39,33,35,93,95,89,91,85,87,81,83,77,79,73,75,69,71,65,67,125,127,121,123,117,119,113,115,109,111,105,107,101,103,97,99,157,159,153,155,149,151,145,147,141,143,137,139,133,135,129,131,189,191,185,187,181,183,177,179,173,175,169,171,165,167,161,163,221,223,217,219,213,215,209,211,205,207,201,203,197,199,193,195,253,255,249,251,245,247,241,243,237,239,233,235,229,231,225,227,0,3,6,5,12,15,10,9,24,27,30,29,20,23,18,17,48,51,54,53,60,63,58,57,40,43,46,45,36,39,34,33,96,99,102,101,108,111,106,105,120,123,126,125,116,119,114,113,80,83,86,85,92,95,90,89,72,75,78,77,68,71,66,65,192,195,198,197,204,207,202,201,216,219,222,221,212,215,210,209,240,243,246,245,252,255,250,249,232,235,238,237,228,231,226,225,160,163,166,165,172,175,170,169,184,187,190,189,180,183,178,177,144,147,150,149,156,159,154,153,136,139,142,141,132,135,130,129,157,158,155,152,145,146,151,148,133,134,131,128,137,138,143,140,173,174,171,168,161,162,167,164,181,182,179,176,185,186,191,188,253,254,251,248,241,242,247,244,229,230,227,224,233,234,239,236,205,206,203,200,193,194,199,196,213,214,211,208,217,218,223,220,93,94,91,88,81,82,87,84,69,70,67,64,73,74,79,76,109,110,107,104,97,98,103,100,117,118,115,112,121,122,127,124,61,62,59,56,49,50,55,52,37,38,35,32,41,42,47,44,13,14,11,8,1,2,7,4,21,22,19,16,25,26,31,28,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,29,25,21,17,13,9,5,1,61,57,53,49,45,41,37,33,93,89,85,81,77,73,69,65,125,121,117,113,109,105,101,97,157,153,149,145,141,137,133,129,189,185,181,177,173,169,165,161,221,217,213,209,205,201,197,193,253,249,245,241,237,233,229,225,58,62,50,54,42,46,34,38,26,30,18,22,10,14,2,6,122,126,114,118,106,110,98,102,90,94,82,86,74,78,66,70,186,190,178,182,170,174,162,166,154,158,146,150,138,142,130,134,250,254,242,246,234,238,226,230,218,222,210,214,202,206,194,198,39,35,47,43,55,51,63,59,7,3,15,11,23,19,31,27,103,99,111,107,119,115,127,123,71,67,79,75,87,83,95,91,167,163,175,171,183,179,191,187,135,131,143,139,151,147,159,155,231,227,239,235,247,243,255,251,199,195,207,203,215,211,223,219,0,5,10,15,20,17,30,27,40,45,34,39,60,57,54,51,80,85,90,95,68,65,78,75,120,125,114,119,108,105,102,99,160,165,170,175,180,177,190,187,136,141,130,135,156,153,150,147,240,245,250,255,228,225,238,235,216,221,210,215,204,201,198,195,93,88,87,82,73,76,67,70,117,112,127,122,97,100,107,110,13,8,7,2,25,28,19,22,37,32,47,42,49,52,59,62,253,248,247,242,233,236,227,230,213,208,223,218,193,196,203,206,173,168,167,162,185,188,179,182,133,128,143,138,145,148,155,158,186,191,176,181,174,171,164,161,146,151,152,157,134,131,140,137,234,239,224,229,254,251,244,241,194,199,200,205,214,211,220,217,26,31,16,21,14,11,4,1,50,55,56,61,38,35,44,41,74,79,64,69,94,91,84,81,98,103,104,109,118,115,124,121,231,226,237,232,243,246,249,252,207,202,197,192,219,222,209,212,183,178,189,184,163,166,169,172,159,154,149,144,139,142,129,132,71,66,77,72,83,86,89,92,111,106,101,96,123,126,113,116,23,18,29,24,3,6,9,12,63,58,53,48,43,46,33,36,0,6,12,10,24,30,20,18,48,54,60,58,40,46,36,34,96,102,108,106,120,126,116,114,80,86,92,90,72,78,68,66,192,198,204,202,216,222,212,210,240,246,252,250,232,238,228,226,160,166,172,170,184,190,180,178,144,150,156,154,136,142,132,130,157,155,145,151,133,131,137,143,173,171,161,167,181,179,185,191,253,251,241,247,229,227,233,239,205,203,193,199,213,211,217,223,93,91,81,87,69,67,73,79,109,107,97,103,117,115,121,127,61,59,49,55,37,35,41,47,13,11,1,7,21,19,25,31,39,33,43,45,63,57,51,53,23,17,27,29,15,9,3,5,71,65,75,77,95,89,83,85,119,113,123,125,111,105,99,101,231,225,235,237,255,249,243,245,215,209,219,221,207,201,195,197,135,129,139,141,159,153,147,149,183,177,187,189,175,169,163,165,186,188,182,176,162,164,174,168,138,140,134,128,146,148,158,152,218,220,214,208,194,196,206,200,234,236,230,224,242,244,254,248,122,124,118,112,98,100,110,104,74,76,70,64,82,84,94,88,26,28,22,16,2,4,14,8,42,44,38,32,50,52,62,56,0,7,14,9,28,27,18,21,56,63,54,49,36,35,42,45,112,119,126,121,108,107,98,101,72,79,70,65,84,83,90,93,224,231,238,233,252,251,242,245,216,223,214,209,196,195,202,205,144,151,158,153,140,139,130,133,168,175,166,161,180,179,186,189,221,218,211,212,193,198,207,200,229,226,235,236,249,254,247,240,173,170,163,164,177,182,191,184,149,146,155,156,137,142,135,128,61,58,51,52,33,38,47,40,5,2,11,12,25,30,23,16,77,74,67,68,81,86,95,88,117,114,123,124,105,110,103,96,167,160,169,174,187,188,181,178,159,152,145,150,131,132,141,138,215,208,217,222,203,204,197,194,239,232,225,230,243,244,253,250,71,64,73,78,91,92,85,82,127,120,113,118,99,100,109,106,55,48,57,62,43,44,37,34,15,8,1,6,19,20,29,26,122,125,116,115,102,97,104,111,66,69,76,75,94,89,80,87,10,13,4,3,22,17,24,31,50,53,60,59,46,41,32,39,154,157,148,147,134,129,136,143,162,165,172,171,190,185,176,183,234,237,228,227,246,241,248,255,210,213,220,219,206,201,192,199,0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,29,21,13,5,61,53,45,37,93,85,77,69,125,117,109,101,157,149,141,133,189,181,173,165,221,213,205,197,253,245,237,229,58,50,42,34,26,18,10,2,122,114,106,98,90,82,74,66,186,178,170,162,154,146,138,130,250,242,234,226,218,210,202,194,39,47,55,63,7,15,23,31,103,111,119,127,71,79,87,95,167,175,183,191,135,143,151,159,231,239,247,255,199,207,215,223,116,124,100,108,84,92,68,76,52,60,36,44,20,28,4,12,244,252,228,236,212,220,196,204,180,188,164,172,148,156,132,140,105,97,121,113,73,65,89,81,41,33,57,49,9,1,25,17,233,225,249,241,201,193,217,209,169,161,185,177,137,129,153,145,78,70,94,86,110,102,126,118,14,6,30,22,46,38,62,54,206,198,222,214,238,230,254,246,142,134,158,150,174,166,190,182,83,91,67,75,115,123,99,107,19,27,3,11,51,59,35,43,211,219,195,203,243,251,227,235,147,155,131,139,179,187,163,171,0,9,18,27,36,45,54,63,72,65,90,83,108,101,126,119,144,153,130,139,180,189,166,175,216,209,202,195,252,245,238,231,61,52,47,38,25,16,11,2,117,124,103,110,81,88,67,74,173,164,191,182,137,128,155,146,229,236,247,254,193,200,211,218,122,115,104,97,94,87,76,69,50,59,32,41,22,31,4,13,234,227,248,241,206,199,220,213,162,171,176,185,134,143,148,157,71,78,85,92,99,106,113,120,15,6,29,20,43,34,57,48,215,222,197,204,243,250,225,232,159,150,141,132,187,178,169,160,244,253,230,239,208,217,194,203,188,181,174,167,152,145,138,131,100,109,118,127,64,73,82,91,44,37,62,55,8,1,26,19,201,192,219,210,237,228,255,246,129,136,147,154,165,172,183,190,89,80,75,66,125,116,111,102,17,24,3,10,53,60,39,46,142,135,156,149,170,163,184,177,198,207,212,221,226,235,240,249,30,23,12,5,58,51,40,33,86,95,68,77,114,123,96,105,179,186,161,168,151,158,133,140,251,242,233,224,223,214,205,196,35,42,49,56,7,14,21,28,107,98,121,112,79,70,93,84,0,10,20,30,40,34,60,54,80,90,68,78,120,114,108,102,160,170,180,190,136,130,156,150,240,250,228,238,216,210,204,198,93,87,73,67,117,127,97,107,13,7,25,19,37,47,49,59,253,247,233,227,213,223,193,203,173,167,185,179,133,143,145,155,186,176,174,164,146,152,134,140,234,224,254,244,194,200,214,220,26,16,14,4,50,56,38,44,74,64,94,84,98,104,118,124,231,237,243,249,207,197,219,209,183,189,163,169,159,149,139,129,71,77,83,89,111,101,123,113,23,29,3,9,63,53,43,33,105,99,125,119,65,75,85,95,57,51,45,39,17,27,5,15,201,195,221,215,225,235,245,255,153,147,141,135,177,187,165,175,52,62,32,42,28,22,8,2,100,110,112,122,76,70,88,82,148,158,128,138,188,182,168,162,196,206,208,218,236,230,248,242,211,217,199,205,251,241,239,229,131,137,151,157,171,161,191,181,115,121,103,109,91,81,79,69,35,41,55,61,11,1,31,21,142,132,154,144,166,172,178,184,222,212,202,192,246,252,226,232,46,36,58,48,6,12,18,24,126,116,106,96,86,92,66,72,0,11,22,29,44,39,58,49,88,83,78,69,116,127,98,105,176,187,166,173,156,151,138,129,232,227,254,245,196,207,210,217,125,118,107,96,81,90,71,76,37,46,51,56,9,2,31,20,205,198,219,208,225,234,247,252,149,158,131,136,185,178,175,164,250,241,236,231,214,221,192,203,162,169,180,191,142,133,152,147,74,65,92,87,102,109,112,123,18,25,4,15,62,53,40,35,135,140,145,154,171,160,189,182,223,212,201,194,243,248,229,238,55,60,33,42,27,16,13,6,111,100,121,114,67,72,85,94,233,226,255,244,197,206,211,216,177,186,167,172,157,150,139,128,89,82,79,68,117,126,99,104,1,10,23,28,45,38,59,48,148,159,130,137,184,179,174,165,204,199,218,209,224,235,246,253,36,47,50,57,8,3,30,21,124,119,106,97,80,91,70,77,19,24,5,14,63,52,41,34,75,64,93,86,103,108,113,122,163,168,181,190,143,132,153,146,251,240,237,230,215,220,193,202,110,101,120,115,66,73,84,95,54,61,32,43,26,17,12,7,222,213,200,195,242,249,228,239,134,141,144,155,170,161,188,183,0,12,24,20,48,60,40,36,96,108,120,116,80,92,72,68,192,204,216,212,240,252,232,228,160,172,184,180,144,156,136,132,157,145,133,137,173,161,181,185,253,241,229,233,205,193,213,217,93,81,69,73,109,97,117,121,61,49,37,41,13,1,21,25,39,43,63,51,23,27,15,3,71,75,95,83,119,123,111,99,231,235,255,243,215,219,207,195,135,139,159,147,183,187,175,163,186,182,162,174,138,134,146,158,218,214,194,206,234,230,242,254,122,118,98,110,74,70,82,94,26,22,2,14,42,38,50,62,78,66,86,90,126,114,102,106,46,34,54,58,30,18,6,10,142,130,150,154,190,178,166,170,238,226,246,250,222,210,198,202,211,223,203,199,227,239,251,247,179,191,171,167,131,143,155,151,19,31,11,7,35,47,59,55,115,127,107,103,67,79,91,87,105,101,113,125,89,85,65,77,9,5,17,29,57,53,33,45,169,165,177,189,153,149,129,141,201,197,209,221,249,245,225,237,244,248,236,224,196,200,220,208,148,152,140,128,164,168,188,176,52,56,44,32,4,8,28,16,84,88,76,64,100,104,124,112,0,13,26,23,52,57,46,35,104,101,114,127,92,81,70,75,208,221,202,199,228,233,254,243,184,181,162,175,140,129,150,155,189,176,167,170,137,132,147,158,213,216,207,194,225,236,251,246,109,96,119,122,89,84,67,78,5,8,31,18,49,60,43,38,103,106,125,112,83,94,73,68,15,2,21,24,59,54,33,44,183,186,173,160,131,142,153,148,223,210,197,200,235,230,241,252,218,215,192,205,238,227,244,249,178,191,168,165,134,139,156,145,10,7,16,29,62,51,36,41,98,111,120,117,86,91,76,65,206,195,212,217,250,247,224,237,166,171,188,177,146,159,136,133,30,19,4,9,42,39,48,61,118,123,108,97,66,79,88,85,115,126,105,100,71,74,93,80,27,22,1,12,47,34,53,56,163,174,185,180,151,154,141,128,203,198,209,220,255,242,229,232,169,164,179,190,157,144,135,138,193,204,219,214,245,248,239,226,121,116,99,110,77,64,87,90,17,28,11,6,37,40,63,50,20,25,14,3,32,45,58,55,124,113,102,107,72,69,82,95,196,201,222,211,240,253,234,231,172,161,182,187,152,149,130,143,0,14,28,18,56,54,36,42,112,126,108,98,72,70,84,90,224,238,252,242,216,214,196,202,144,158,140,130,168,166,180,186,221,211,193,207,229,235,249,247,173,163,177,191,149,155,137,135,61,51,33,47,5,11,25,23,77,67,81,95,117,123,105,103,167,169,187,181,159,145,131,141,215,217,203,197,239,225,243,253,71,73,91,85,127,113,99,109,55,57,43,37,15,1,19,29,122,116,102,104,66,76,94,80,10,4,22,24,50,60,46,32,154,148,134,136,162,172,190,176,234,228,246,248,210,220,206,192,83,93,79,65,107,101,119,121,35,45,63,49,27,21,7,9,179,189,175,161,139,133,151,153,195,205,223,209,251,245,231,233,142,128,146,156,182,184,170,164,254,240,226,236,198,200,218,212,110,96,114,124,86,88,74,68,30,16,2,12,38,40,58,52,244,250,232,230,204,194,208,222,132,138,152,150,188,178,160,174,20,26,8,6,44,34,48,62,100,106,120,118,92,82,64,78,41,39,53,59,17,31,13,3,89,87,69,75,97,111,125,115,201,199,213,219,241,255,237,227,185,183,165,171,129,143,157,147,0,15,30,17,60,51,34,45,120,119,102,105,68,75,90,85,240,255,238,225,204,195,210,221,136,135,150,153,180,187,170,165,253,242,227,236,193,206,223,208,133,138,155,148,185,182,167,168,13,2,19,28,49,62,47,32,117,122,107,100,73,70,87,88,231,232,249,246,219,212,197,202,159,144,129,142,163,172,189,178,23,24,9,6,43,36,53,58,111,96,113,126,83,92,77,66,26,21,4,11,38,41,56,55,98,109,124,115,94,81,64,79,234,229,244,251,214,217,200,199,146,157,140,131,174,161,176,191,211,220,205,194,239,224,241,254,171,164,181,186,151,152,137,134,35,44,61,50,31,16,1,14,91,84,69,74,103,104,121,118,46,33,48,63,18,29,12,3,86,89,72,71,106,101,116,123,222,209,192,207,226,237,252,243,166,169,184,183,154,149,132,139,52,59,42,37,8,7,22,25,76,67,82,93,112,127,110,97,196,203,218,213,248,247,230,233,188,179,162,173,128,143,158,145,201,198,215,216,245,250,235,228,177,190,175,160,141,130,147,156,57,54,39,40,5,10,27,20,65,78,95,80,125,114,99,108,0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,29,13,61,45,93,77,125,109,157,141,189,173,221,205,253,237,58,42,26,10,122,106,90,74,186,170,154,138,250,234,218,202,39,55,7,23,103,119,71,87,167,183,135,151,231,247,199,215,116,100,84,68,52,36,20,4,244,228,212,196,180,164,148,132,105,121,73,89,41,57,9,25,233,249,201,217,169,185,137,153,78,94,110,126,14,30,46,62,206,222,238,254,142,158,174,190,83,67,115,99,19,3,51,35,211,195,243,227,147,131,179,163,232,248,200,216,168,184,136,152,104,120,72,88,40,56,8,24,245,229,213,197,181,165,149,133,117,101,85,69,53,37,21,5,210,194,242,226,146,130,178,162,82,66,114,98,18,2,50,34,207,223,239,255,143,159,175,191,79,95,111,127,15,31,47,63,156,140,188,172,220,204,252,236,28,12,60,44,92,76,124,108,129,145,161,177,193,209,225,241,1,17,33,49,65,81,97,113,166,182,134,150,230,246,198,214,38,54,6,22,102,118,70,86,187,171,155,139,251,235,219,203,59,43,27,11,123,107,91,75,0,17,34,51,68,85,102,119,136,153,170,187,204,221,238,255,13,28,47,62,73,88,107,122,133,148,167,182,193,208,227,242,26,11,56,41,94,79,124,109,146,131,176,161,214,199,244,229,23,6,53,36,83,66,113,96,159,142,189,172,219,202,249,232,52,37,22,7,112,97,82,67,188,173,158,143,248,233,218,203,57,40,27,10,125,108,95,78,177,160,147,130,245,228,215,198,46,63,12,29,106,123,72,89,166,183,132,149,226,243,192,209,35,50,1,16,103,118,69,84,171,186,137,152,239,254,205,220,104,121,74,91,44,61,14,31,224,241,194,211,164,181,134,151,101,116,71,86,33,48,3,18,237,252,207,222,169,184,139,154,114,99,80,65,54,39,20,5,250,235,216,201,190,175,156,141,127,110,93,76,59,42,25,8,247,230,213,196,179,162,145,128,92,77,126,111,24,9,58,43,212,197,246,231,144,129,178,163,81,64,115,98,21,4,55,38,217,200,251,234,157,140,191,174,70,87,100,117,2,19,32,49,206,223,236,253,138,155,168,185,75,90,105,120,15,30,45,60,195,210,225,240,135,150,165,180,0,18,36,54,72,90,108,126,144,130,180,166,216,202,252,238,61,47,25,11,117,103,81,67,173,191,137,155,229,247,193,211,122,104,94,76,50,32,22,4,234,248,206,220,162,176,134,148,71,85,99,113,15,29,43,57,215,197,243,225,159,141,187,169,244,230,208,194,188,174,152,138,100,118,64,82,44,62,8,26,201,219,237,255,129,147,165,183,89,75,125,111,17,3,53,39,142,156,170,184,198,212,226,240,30,12,58,40,86,68,114,96,179,161,151,133,251,233,223,205,35,49,7,21,107,121,79,93,245,231,209,195,189,175,153,139,101,119,65,83,45,63,9,27,200,218,236,254,128,146,164,182,88,74,124,110,16,2,52,38,143,157,171,185,199,213,227,241,31,13,59,41,87,69,115,97,178,160,150,132,250,232,222,204,34,48,6,20,106,120,78,92,1,19,37,55,73,91,109,127,145,131,181,167,217,203,253,239,60,46,24,10,116,102,80,66,172,190,136,154,228,246,192,210,123,105,95,77,51,33,23,5,235,249,207,221,163,177,135,149,70,84,98,112,14,28,42,56,214,196,242,224,158,140,186,168,0,19,38,53,76,95,106,121,152,139,190,173,212,199,242,225,45,62,11,24,97,114,71,84,181,166,147,128,249,234,223,204,90,73,124,111,22,5,48,35,194,209,228,247,142,157,168,187,119,100,81,66,59,40,29,14,239,252,201,218,163,176,133,150,180,167,146,129,248,235,222,205,44,63,10,25,96,115,70,85,153,138,191,172,213,198,243,224,1,18,39,52,77,94,107,120,238,253,200,219,162,177,132,151,118,101,80,67,58,41,28,15,195,208,229,246,143,156,169,186,91,72,125,110,23,4,49,34,117,102,83,64,57,42,31,12,237,254,203,216,161,178,135,148,88,75,126,109,20,7,50,33,192,211,230,245,140,159,170,185,47,60,9,26,99,112,69,86,183,164,145,130,251,232,221,206,2,17,36,55,78,93,104,123,154,137,188,175,214,197,240,227,193,210,231,244,141,158,171,184,89,74,127,108,21,6,51,32,236,255,202,217,160,179,134,149,116,103,82,65,56,43,30,13,155,136,189,174,215,196,241,226,3,16,37,54,79,92,105,122,182,165,144,131,250,233,220,207,46,61,8,27,98,113,68,87,0,20,40,60,80,68,120,108,160,180,136,156,240,228,216,204,93,73,117,97,13,25,37,49,253,233,213,193,173,185,133,145,186,174,146,134,234,254,194,214,26,14,50,38,74,94,98,118,231,243,207,219,183,163,159,139,71,83,111,123,23,3,63,43,105,125,65,85,57,45,17,5,201,221,225,245,153,141,177,165,52,32,28,8,100,112,76,88,148,128,188,168,196,208,236,248,211,199,251,239,131,151,171,191,115,103,91,79,35,55,11,31,142,154,166,178,222,202,246,226,46,58,6,18,126,106,86,66,210,198,250,238,130,150,170,190,114,102,90,78,34,54,10,30,143,155,167,179,223,203,247,227,47,59,7,19,127,107,87,67,104,124,64,84,56,44,16,4,200,220,224,244,152,140,176,164,53,33,29,9,101,113,77,89,149,129,189,169,197,209,237,249,187,175,147,135,235,255,195,215,27,15,51,39,75,95,99,119,230,242,206,218,182,162,158,138,70,82,110,122,22,2,62,42,1,21,41,61,81,69,121,109,161,181,137,157,241,229,217,205,92,72,116,96,12,24,36,48,252,232,212,192,172,184,132,144,0,21,42,63,84,65,126,107,168,189,130,151,252,233,214,195,77,88,103,114,25,12,51,38,229,240,207,218,177,164,155,142,154,143,176,165,206,219,228,241,50,39,24,13,102,115,76,89,215,194,253,232,131,150,169,188,127,106,85,64,43,62,1,20,41,60,3,22,125,104,87,66,129,148,171,190,213,192,255,234,100,113,78,91,48,37,26,15,204,217,230,243,152,141,178,167,179,166,153,140,231,242,205,216,27,14,49,36,79,90,101,112,254,235,212,193,170,191,128,149,86,67,124,105,2,23,40,61,82,71,120,109,6,19,44,57,250,239,208,197,174,187,132,145,31,10,53,32,75,94,97,116,183,162,157,136,227,246,201,220,200,221,226,247,156,137,182,163,96,117,74,95,52,33,30,11,133,144,175,186,209,196,251,238,45,56,7,18,121,108,83,70,123,110,81,68,47,58,5,16,211,198,249,236,135,146,173,184,54,35,28,9,98,119,72,93,158,139,180,161,202,223,224,245,225,244,203,222,181,160,159,138,73,92,99,118,29,8,55,34,172,185,134,147,248,237,210,199,4,17,46,59,80,69,122,111,0,22,44,58,88,78,116,98,176,166,156,138,232,254,196,210,125,107,81,71,37,51,9,31,205,219,225,247,149,131,185,175,250,236,214,192,162,180,142,152,74,92,102,112,18,4,62,40,135,145,171,189,223,201,243,229,55,33,27,13,111,121,67,85,233,255,197,211,177,167,157,139,89,79,117,99,1,23,45,59,148,130,184,174,204,218,224,246,36,50,8,30,124,106,80,70,19,5,63,41,75,93,103,113,163,181,143,153,251,237,215,193,110,120,66,84,54,32,26,12,222,200,242,228,134,144,170,188,207,217,227,245,151,129,187,173,127,105,83,69,39,49,11,29,178,164,158,136,234,252,198,208,2,20,46,56,90,76,118,96,53,35,25,15,109,123,65,87,133,147,169,191,221,203,241,231,72,94,100,114,16,6,60,42,248,238,212,194,160,182,140,154,38,48,10,28,126,104,82,68,150,128,186,172,206,216,226,244,91,77,119,97,3,21,47,57,235,253,199,209,179,165,159,137,220,202,240,230,132,146,168,190,108,122,64,86,52,34,24,14,161,183,141,155,249,239,213,195,17,7,61,43,73,95,101,115,0,23,46,57,92,75,114,101,184,175,150,129,228,243,202,221,109,122,67,84,49,38,31,8,213,194,251,236,137,158,167,176,218,205,244,227,134,145,168,191,98,117,76,91,62,41,16,7,183,160,153,142,235,252,197,210,15,24,33,54,83,68,125,106,169,190,135,144,245,226,219,204,17,6,63,40,77,90,99,116,196,211,234,253,152,143,182,161,124,107,82,69,32,55,14,25,115,100,93,74,47,56,1,22,203,220,229,242,151,128,185,174,30,9,48,39,66,85,108,123,166,177,136,159,250,237,212,195,79,88,97,118,19,4,61,42,247,224,217,206,171,188,133,146,34,53,12,27,126,105,80,71,154,141,180,163,198,209,232,255,149,130,187,172,201,222,231,240,45,58,3,20,113,102,95,72,248,239,214,193,164,179,138,157,64,87,110,121,28,11,50,37,230,241,200,223,186,173,148,131,94,73,112,103,2,21,44,59,139,156,165,178,215,192,249,238,51,36,29,10,111,120,65,86,60,43,18,5,96,119,78,89,132,147,170,189,216,207,246,225,81,70,127,104,13,26,35,52,233,254,199,208,181,162,155,140,0,24,48,40,96,120,80,72,192,216,240,232,160,184,144,136,157,133,173,181,253,229,205,213,93,69,109,117,61,37,13,21,39,63,23,15,71,95,119,111,231,255,215,207,135,159,183,175,186,162,138,146,218,194,234,242,122,98,74,82,26,2,42,50,78,86,126,102,46,54,30,6,142,150,190,166,238,246,222,198,211,203,227,251,179,171,131,155,19,11,35,59,115,107,67,91,105,113,89,65,9,17,57,33,169,177,153,129,201,209,249,225,244,236,196,220,148,140,164,188,52,44,4,28,84,76,100,124,156,132,172,180,252,228,204,212,92,68,108,116,60,36,12,20,1,25,49,41,97,121,81,73,193,217,241,233,161,185,145,137,187,163,139,147,219,195,235,243,123,99,75,83,27,3,43,51,38,62,22,14,70,94,118,110,230,254,214,206,134,158,182,174,210,202,226,250,178,170,130,154,18,10,34,58,114,106,66,90,79,87,127,103,47,55,31,7,143,151,191,167,239,247,223,199,245,237,197,221,149,141,165,189,53,45,5,29,85,77,101,125,104,112,88,64,8,16,56,32,168,176,152,128,200,208,248,224,0,25,50,43,100,125,86,79,200,209,250,227,172,181,158,135,141,148,191,166,233,240,219,194,69,92,119,110,33,56,19,10,7,30,53,44,99,122,81,72,207,214,253,228,171,178,153,128,138,147,184,161,238,247,220,197,66,91,112,105,38,63,20,13,14,23,60,37,106,115,88,65,198,223,244,237,162,187,144,137,131,154,177,168,231,254,213,204,75,82,121,96,47,54,29,4,9,16,59,34,109,116,95,70,193,216,243,234,165,188,151,142,132,157,182,175,224,249,210,203,76,85,126,103,40,49,26,3,28,5,46,55,120,97,74,83,212,205,230,255,176,169,130,155,145,136,163,186,245,236,199,222,89,64,107,114,61,36,15,22,27,2,41,48,127,102,77,84,211,202,225,248,183,174,133,156,150,143,164,189,242,235,192,217,94,71,108,117,58,35,8,17,18,11,32,57,118,111,68,93,218,195,232,241,190,167,140,149,159,134,173,180,251,226,201,208,87,78,101,124,51,42,1,24,21,12,39,62,113,104,67,90,221,196,239,246,185,160,139,146,152,129,170,179,252,229,206,215,80,73,98,123,52,45,6,31,0,26,52,46,104,114,92,70,208,202,228,254,184,162,140,150,189,167,137,147,213,207,225,251,109,119,89,67,5,31,49,43,103,125,83,73,15,21,59,33,183,173,131,153,223,197,235,241,218,192,238,244,178,168,134,156,10,16,62,36,98,120,86,76,206,212,250,224,166,188,146,136,30,4,42,48,118,108,66,88,115,105,71,93,27,1,47,53,163,185,151,141,203,209,255,229,169,179,157,135,193,219,245,239,121,99,77,87,17,11,37,63,20,14,32,58,124,102,72,82,196,222,240,234,172,182,152,130,129,155,181,175,233,243,221,199,81,75,101,127,57,35,13,23,60,38,8,18,84,78,96,122,236,246,216,194,132,158,176,170,230,252,210,200,142,148,186,160,54,44,2,24,94,68,106,112,91,65,111,117,51,41,7,29,139,145,191,165,227,249,215,205,79,85,123,97,39,61,19,9,159,133,171,177,247,237,195,217,242,232,198,220,154,128,174,180,34,56,22,12,74,80,126,100,40,50,28,6,64,90,116,110,248,226,204,214,144,138,164,190,149,143,161,187,253,231,201,211,69,95,113,107,45,55,25,3,0,27,54,45,108,119,90,65,216,195,238,245,180,175,130,153,173,182,155,128,193,218,247,236,117,110,67,88,25,2,47,52,71,92,113,106,43,48,29,6,159,132,169,178,243,232,197,222,234,241,220,199,134,157,176,171,50,41,4,31,94,69,104,115,142,149,184,163,226,249,212,207,86,77,96,123,58,33,12,23,35,56,21,14,79,84,121,98,251,224,205,214,151,140,161,186,201,210,255,228,165,190,147,136,17,10,39,60,125,102,75,80,100,127,82,73,8,19,62,37,188,167,138,145,208,203,230,253,1,26,55,44,109,118,91,64,217,194,239,244,181,174,131,152,172,183,154,129,192,219,246,237,116,111,66,89,24,3,46,53,70,93,112,107,42,49,28,7,158,133,168,179,242,233,196,223,235,240,221,198,135,156,177,170,51,40,5,30,95,68,105,114,143,148,185,162,227,248,213,206,87,76,97,122,59,32,13,22,34,57,20,15,78,85,120,99,250,225,204,215,150,141,160,187,200,211,254,229,164,191,146,137,16,11,38,61,124,103,74,81,101,126,83,72,9,18,63,36,189,166,139,144,209,202,231,252,0,28,56,36,112,108,72,84,224,252,216,196,144,140,168,180,221,193,229,249,173,177,149,137,61,33,5,25,77,81,117,105,167,187,159,131,215,203,239,243,71,91,127,99,55,43,15,19,122,102,66,94,10,22,50,46,154,134,162,190,234,246,210,206,83,79,107,119,35,63,27,7,179,175,139,151,195,223,251,231,142,146,182,170,254,226,198,218,110,114,86,74,30,2,38,58,244,232,204,208,132,152,188,160,20,8,44,48,100,120,92,64,41,53,17,13,89,69,97,125,201,213,241,237,185,165,129,157,166,186,158,130,214,202,238,242,70,90,126,98,54,42,14,18,123,103,67,95,11,23,51,47,155,135,163,191,235,247,211,207,1,29,57,37,113,109,73,85,225,253,217,197,145,141,169,181,220,192,228,248,172,176,148,136,60,32,4,24,76,80,116,104,245,233,205,209,133,153,189,161,21,9,45,49,101,121,93,65,40,52,16,12,88,68,96,124,200,212,240,236,184,164,128,156,82,78,106,118,34,62,26,6,178,174,138,150,194,222,250,230,143,147,183,171,255,227,199,219,111,115,87,75,31,3,39,59,0,29,58,39,116,105,78,83,232,245,210,207,156,129,166,187,205,208,247,234,185,164,131,158,37,56,31,2,81,76,107,118,135,154,189,160,243,238,201,212,111,114,85,72,27,6,33,60,74,87,112,109,62,35,4,25,162,191,152,133,214,203,236,241,19,14,41,52,103,122,93,64,251,230,193,220,143,146,181,168,222,195,228,249,170,183,144,141,54,43,12,17,66,95,120,101,148,137,174,179,224,253,218,199,124,97,70,91,8,21,50,47,89,68,99,126,45,48,23,10,177,172,139,150,197,216,255,226,38,59,28,1,82,79,104,117,206,211,244,233,186,167,128,157,235,246,209,204,159,130,165,184,3,30,57,36,119,106,77,80,161,188,155,134,213,200,239,242,73,84,115,110,61,32,7,26,108,113,86,75,24,5,34,63,132,153,190,163,240,237,202,215,53,40,15,18,65,92,123,102,221,192,231,250,169,180,147,142,248,229,194,223,140,145,182,171,16,13,42,55,100,121,94,67,178,175,136,149,198,219,252,225,90,71,96,125,46,51,20,9,127,98,69,88,11,22,49,44,151,138,173,176,227,254,217,196,0,30,60,34,120,102,68,90,240,238,204,210,136,150,180,170,253,227,193,223,133,155,185,167,13,19,49,47,117,107,73,87,231,249,219,197,159,129,163,189,23,9,43,53,111,113,83,77,26,4,38,56,98,124,94,64,234,244,214,200,146,140,174,176,211,205,239,241,171,181,151,137,35,61,31,1,91,69,103,121,46,48,18,12,86,72,106,116,222,192,226,252,166,184,154,132,52,42,8,22,76,82,112,110,196,218,248,230,188,162,128,158,201,215,245,235,177,175,141,147,57,39,5,27,65,95,125,99,187,165,135,153,195,221,255,225,75,85,119,105,51,45,15,17,70,88,122,100,62,32,2,28,182,168,138,148,206,208,242,236,92,66,96,126,36,58,24,6,172,178,144,142,212,202,232,246,161,191,157,131,217,199,229,251,81,79,109,115,41,55,21,11,104,118,84,74,16,14,44,50,152,134,164,186,224,254,220,194,149,139,169,183,237,243,209,207,101,123,89,71,29,3,33,63,143,145,179,173,247,233,203,213,127,97,67,93,7,25,59,37,114,108,78,80,10,20,54,40,130,156,190,160,250,228,198,216,0,31,62,33,124,99,66,93,248,231,198,217,132,155,186,165,237,242,211,204,145,142,175,176,21,10,43,52,105,118,87,72,199,216,249,230,187,164,133,154,63,32,1,30,67,92,125,98,42,53,20,11,86,73,104,119,210,205,236,243,174,177,144,143,147,140,173,178,239,240,209,206,107,116,85,74,23,8,41,54,126,97,64,95,2,29,60,35,134,153,184,167,250,229,196,219,84,75,106,117,40,55,22,9,172,179,146,141,208,207,238,241,185,166,135,152,197,218,251,228,65,94,127,96,61,34,3,28,59,36,5,26,71,88,121,102,195,220,253,226,191,160,129,158,214,201,232,247,170,181,148,139,46,49,16,15,82,77,108,115,252,227,194,221,128,159,190,161,4,27,58,37,120,103,70,89,17,14,47,48,109,114,83,76,233,246,215,200,149,138,171,180,168,183,150,137,212,203,234,245,80,79,110,113,44,51,18,13,69,90,123,100,57,38,7,24,189,162,131,156,193,222,255,224,111,112,81,78,19,12,45,50,151,136,169,182,235,244,213,202,130,157,188,163,254,225,192,223,122,101,68,91,6,25,56,39,0,32,64,96,128,160,192,224,29,61,93,125,157,189,221,253,58,26,122,90,186,154,250,218,39,7,103,71,167,135,231,199,116,84,52,20,244,212,180,148,105,73,41,9,233,201,169,137,78,110,14,46,206,238,142,174,83,115,19,51,211,243,147,179,232,200,168,136,104,72,40,8,245,213,181,149,117,85,53,21,210,242,146,178,82,114,18,50,207,239,143,175,79,111,15,47,156,188,220,252,28,60,92,124,129,161,193,225,1,33,65,97,166,134,230,198,38,6,102,70,187,155,251,219,59,27,123,91,205,237,141,173,77,109,13,45,208,240,144,176,80,112,16,48,247,215,183,151,119,87,55,23,234,202,170,138,106,74,42,10,185,153,249,217,57,25,121,89,164,132,228,196,36,4,100,68,131,163,195,227,3,35,67,99,158,190,222,254,30,62,94,126,37,5,101,69,165,133,229,197,56,24,120,88,184,152,248,216,31,63,95,127,159,191,223,255,2,34,66,98,130,162,194,226,81,113,17,49,209,241,145,177,76,108,12,44,204,236,140,172,107,75,43,11,235,203,171,139,118,86,54,22,246,214,182,150,0,33,66,99,132,165,198,231,21,52,87,118,145,176,211,242,42,11,104,73,174,143,236,205,63,30,125,92,187,154,249,216,84,117,22,55,208,241,146,179,65,96,3,34,197,228,135,166,126,95,60,29,250,219,184,153,107,74,41,8,239,206,173,140,168,137,234,203,44,13,110,79,189,156,255,222,57,24,123,90,130,163,192,225,6,39,68,101,151,182,213,244,19,50,81,112,252,221,190,159,120,89,58,27,233,200,171,138,109,76,47,14,214,247,148,181,82,115,16,49,195,226,129,160,71,102,5,36,77,108,15,46,201,232,139,170,88,121,26,59,220,253,158,191,103,70,37,4,227,194,161,128,114,83,48,17,246,215,180,149,25,56,91,122,157,188,223,254,12,45,78,111,136,169,202,235,51,18,113,80,183,150,245,212,38,7,100,69,162,131,224,193,229,196,167,134,97,64,35,2,240,209,178,147,116,85,54,23,207,238,141,172,75,106,9,40,218,251,152,185,94,127,28,61,177,144,243,210,53,20,119,86,164,133,230,199,32,1,98,67,155,186,217,248,31,62,93,124,142,175,204,237,10,43,72,105,0,34,68,102,136,170,204,238,13,47,73,107,133,167,193,227,26,56,94,124,146,176,214,244,23,53,83,113,159,189,219,249,52,22,112,82,188,158,248,218,57,27,125,95,177,147,245,215,46,12,106,72,166,132,226,192,35,1,103,69,171,137,239,205,104,74,44,14,224,194,164,134,101,71,33,3,237,207,169,139,114,80,54,20,250,216,190,156,127,93,59,25,247,213,179,145,92,126,24,58,212,246,144,178,81,115,21,55,217,251,157,191,70,100,2,32,206,236,138,168,75,105,15,45,195,225,135,165,208,242,148,182,88,122,28,62,221,255,153,187,85,119,17,51,202,232,142,172,66,96,6,36,199,229,131,161,79,109,11,41,228,198,160,130,108,78,40,10,233,203,173,143,97,67,37,7,254,220,186,152,118,84,50,16,243,209,183,149,123,89,63,29,184,154,252,222,48,18,116,86,181,151,241,211,61,31,121,91,162,128,230,196,42,8,110,76,175,141,235,201,39,5,99,65,140,174,200,234,4,38,64,98,129,163,197,231,9,43,77,111,150,180,210,240,30,60,90,120,155,185,223,253,19,49,87,117,0,35,70,101,140,175,202,233,5,38,67,96,137,170,207,236,10,41,76,111,134,165,192,227,15,44,73,106,131,160,197,230,20,55,82,113,152,187,222,253,17,50,87,116,157,190,219,248,30,61,88,123,146,177,212,247,27,56,93,126,151,180,209,242,40,11,110,77,164,135,226,193,45,14,107,72,161,130,231,196,34,1,100,71,174,141,232,203,39,4,97,66,171,136,237,206,60,31,122,89,176,147,246,213,57,26,127,92,181,150,243,208,54,21,112,83,186,153,252,223,51,16,117,86,191,156,249,218,80,115,22,53,220,255,154,185,85,118,19,48,217,250,159,188,90,121,28,63,214,245,144,179,95,124,25,58,211,240,149,182,68,103,2,33,200,235,142,173,65,98,7,36,205,238,139,168,78,109,8,43,194,225,132,167,75,104,13,46,199,228,129,162,120,91,62,29,244,215,178,145,125,94,59,24,241,210,183,148,114,81,52,23,254,221,184,155,119,84,49,18,251,216,189,158,108,79,42,9,224,195,166,133,105,74,47,12,229,198,163,128,102,69,32,3,234,201,172,143,99,64,37,6,239,204,169,138,0,36,72,108,144,180,216,252,61,25,117,81,173,137,229,193,122,94,50,22,234,206,162,134,71,99,15,43,215,243,159,187,244,208,188,152,100,64,44,8,201,237,129,165,89,125,17,53,142,170,198,226,30,58,86,114,179,151,251,223,35,7,107,79,245,209,189,153,101,65,45,9,200,236,128,164,88,124,16,52,143,171,199,227,31,59,87,115,178,150,250,222,34,6,106,78,1,37,73,109,145,181,217,253,60,24,116,80,172,136,228,192,123,95,51,23,235,207,163,135,70,98,14,42,214,242,158,186,247,211,191,155,103,67,47,11,202,238,130,166,90,126,18,54,141,169,197,225,29,57,85,113,176,148,248,220,32,4,104,76,3,39,75,111,147,183,219,255,62,26,118,82,174,138,230,194,121,93,49,21,233,205,161,133,68,96,12,40,212,240,156,184,2,38,74,110,146,182,218,254,63,27,119,83,175,139,231,195,120,92,48,20,232,204,160,132,69,97,13,41,213,241,157,185,246,210,190,154,102,66,46,10,203,239,131,167,91,127,19,55,140,168,196,224,28,56,84,112,177,149,249,221,33,5,105,77,0,37,74,111,148,177,222,251,53,16,127,90,161,132,235,206,106,79,32,5,254,219,180,145,95,122,21,48,203,238,129,164,212,241,158,187,64,101,10,47,225,196,171,142,117,80,63,26,190,155,244,209,42,15,96,69,139,174,193,228,31,58,85,112,181,144,255,218,33,4,107,78,128,165,202,239,20,49,94,123,223,250,149,176,75,110,1,36,234,207,160,133,126,91,52,17,97,68,43,14,245,208,191,154,84,113,30,59,192,229,138,175,11,46,65,100,159,186,213,240,62,27,116,81,170,143,224,197,119,82,61,24,227,198,169,140,66,103,8,45,214,243,156,185,29,56,87,114,137,172,195,230,40,13,98,71,188,153,246,211,163,134,233,204,55,18,125,88,150,179,220,249,2,39,72,109,201,236,131,166,93,120,23,50,252,217,182,147,104,77,34,7,194,231,136,173,86,115,28,57,247,210,189,152,99,70,41,12,168,141,226,199,60,25,118,83,157,184,215,242,9,44,67,102,22,51,92,121,130,167,200,237,35,6,105,76,183,146,253,216,124,89,54,19,232,205,162,135,73,108,3,38,221,248,151,178,0,38,76,106,152,190,212,242,45,11,97,71,181,147,249,223,90,124,22,48,194,228,142,168,119,81,59,29,239,201,163,133,180,146,248,222,44,10,96,70,153,191,213,243,1,39,77,107,238,200,162,132,118,80,58,28,195,229,143,169,91,125,23,49,117,83,57,31,237,203,161,135,88,126,20,50,192,230,140,170,47,9,99,69,183,145,251,221,2,36,78,104,154,188,214,240,193,231,141,171,89,127,21,51,236,202,160,134,116,82,56,30,155,189,215,241,3,37,79,105,182,144,250,220,46,8,98,68,234,204,166,128,114,84,62,24,199,225,139,173,95,121,19,53,176,150,252,218,40,14,100,66,157,187,209,247,5,35,73,111,94,120,18,52,198,224,138,172,115,85,63,25,235,205,167,129,4,34,72,110,156,186,208,246,41,15,101,67,177,151,253,219,159,185,211,245,7,33,75,109,178,148,254,216,42,12,102,64,197,227,137,175,93,123,17,55,232,206,164,130,112,86,60,26,43,13,103,65,179,149,255,217,6,32,74,108,158,184,210,244,113,87,61,27,233,207,165,131,92,122,16,54,196,226,136,174,0,39,78,105,156,187,210,245,37,2,107,76,185,158,247,208,74,109,4,35,214,241,152,191,111,72,33,6,243,212,189,154,148,179,218,253,8,47,70,97,177,150,255,216,45,10,99,68,222,249,144,183,66,101,12,43,251,220,181,146,103,64,41,14,53,18,123,92,169,142,231,192,16,55,94,121,140,171,194,229,127,88,49,22,227,196,173,138,90,125,20,51,198,225,136,175,161,134,239,200,61,26,115,84,132,163,202,237,24,63,86,113,235,204,165,130,119,80,57,30,206,233,128,167,82,117,28,59,106,77,36,3,246,209,184,159,79,104,1,38,211,244,157,186,32,7,110,73,188,155,242,213,5,34,75,108,153,190,215,240,254,217,176,151,98,69,44,11,219,252,149,178,71,96,9,46,180,147,250,221,40,15,102,65,145,182,223,248,13,42,67,100,95,120,17,54,195,228,141,170,122,93,52,19,230,193,168,143,21,50,91,124,137,174,199,224,48,23,126,89,172,139,226,197,203,236,133,162,87,112,25,62,238,201,160,135,114,85,60,27,129,166,207,232,29,58,83,116,164,131,234,205,56,31,118,81,0,40,80,120,160,136,240,216,93,117,13,37,253,213,173,133,186,146,234,194,26,50,74,98,231,207,183,159,71,111,23,63,105,65,57,17,201,225,153,177,52,28,100,76,148,188,196,236,211,251,131,171,115,91,35,11,142,166,222,246,46,6,126,86,210,250,130,170,114,90,34,10,143,167,223,247,47,7,127,87,104,64,56,16,200,224,152,176,53,29,101,77,149,189,197,237,187,147,235,195,27,51,75,99,230,206,182,158,70,110,22,62,1,41,81,121,161,137,241,217,92,116,12,36,252,212,172,132,185,145,233,193,25,49,73,97,228,204,180,156,68,108,20,60,3,43,83,123,163,139,243,219,94,118,14,38,254,214,174,134,208,248,128,168,112,88,32,8,141,165,221,245,45,5,125,85,106,66,58,18,202,226,154,178,55,31,103,79,151,191,199,239,107,67,59,19,203,227,155,179,54,30,102,78,150,190,198,238,209,249,129,169,113,89,33,9,140,164,220,244,44,4,124,84,2,42,82,122,162,138,242,218,95,119,15,39,255,215,175,135,184,144,232,192,24,48,72,96,229,205,181,157,69,109,21,61,0,41,82,123,164,141,246,223,85,124,7,46,241,216,163,138,170,131,248,209,14,39,92,117,255,214,173,132,91,114,9,32,73,96,27,50,237,196,191,150,28,53,78,103,184,145,234,195,227,202,177,152,71,110,21,60,182,159,228,205,18,59,64,105,146,187,192,233,54,31,100,77,199,238,149,188,99,74,49,24,56,17,106,67,156,181,206,231,109,68,63,22,201,224,155,178,219,242,137,160,127,86,45,4,142,167,220,245,42,3,120,81,113,88,35,10,213,252,135,174,36,13,118,95,128,169,210,251,57,16,107,66,157,180,207,230,108,69,62,23,200,225,154,179,147,186,193,232,55,30,101,76,198,239,148,189,98,75,48,25,112,89,34,11,212,253,134,175,37,12,119,94,129,168,211,250,218,243,136,161,126,87,44,5,143,166,221,244,43,2,121,80,171,130,249,208,15,38,93,116,254,215,172,133,90,115,8,33,1,40,83,122,165,140,247,222,84,125,6,47,240,217,162,139,226,203,176,153,70,111,20,61,183,158,229,204,19,58,65,104,72,97,26,51,236,197,190,151,29,52,79,102,185,144,235,194,0,42,84,126,168,130,252,214,77,103,25,51,229,207,177,155,154,176,206,228,50,24,102,76,215,253,131,169,127,85,43,1,41,3,125,87,129,171,213,255,100,78,48,26,204,230,152,178,179,153,231,205,27,49,79,101,254,212,170,128,86,124,2,40,82,120,6,44,250,208,174,132,31,53,75,97,183,157,227,201,200,226,156,182,96,74,52,30,133,175,209,251,45,7,121,83,123,81,47,5,211,249,135,173,54,28,98,72,158,180,202,224,225,203,181,159,73,99,29,55,172,134,248,210,4,46,80,122,164,142,240,218,12,38,88,114,233,195,189,151,65,107,21,63,62,20,106,64,150,188,194,232,115,89,39,13,219,241,143,165,141,167,217,243,37,15,113,91,192,234,148,190,104,66,60,22,23,61,67,105,191,149,235,193,90,112,14,36,242,216,166,140,246,220,162,136,94,116,10,32,187,145,239,197,19,57,71,109,108,70,56,18,196,238,144,186,33,11,117,95,137,163,221,247,223,245,139,161,119,93,35,9,146,184,198,236,58,16,110,68,69,111,17,59,237,199,185,147,8,34,92,118,160,138,244,222,0,43,86,125,172,135,250,209,69,110,19,56,233,194,191,148,138,161,220,247,38,13,112,91,207,228,153,178,99,72,53,30,9,34,95,116,165,142,243,216,76,103,26,49,224,203,182,157,131,168,213,254,47,4,121,82,198,237,144,187,106,65,60,23,18,57,68,111,190,149,232,195,87,124,1,42,251,208,173,134,152,179,206,229,52,31,98,73,221,246,139,160,113,90,39,12,27,48,77,102,183,156,225,202,94,117,8,35,242,217,164,143,145,186,199,236,61,22,107,64,212,255,130,169,120,83,46,5,36,15,114,89,136,163,222,245,97,74,55,28,205,230,155,176,174,133,248,211,2,41,84,127,235,192,189,150,71,108,17,58,45,6,123,80,129,170,215,252,104,67,62,21,196,239,146,185,167,140,241,218,11,32,93,118,226,201,180,159,78,101,24,51,54,29,96,75,154,177,204,231,115,88,37,14,223,244,137,162,188,151,234,193,16,59,70,109,249,210,175,132,85,126,3,40,63,20,105,66,147,184,197,238,122,81,44,7,214,253,128,171,181,158,227,200,25,50,79,100,240,219,166,141,92,119,10,33,0,44,88,116,176,156,232,196,125,81,37,9,205,225,149,185,250,214,162,142,74,102,18,62,135,171,223,243,55,27,111,67,233,197,177,157,89,117,1,45,148,184,204,224,36,8,124,80,19,63,75,103,163,143,251,215,110,66,54,26,222,242,134,170,207,227,151,187,127,83,39,11,178,158,234,198,2,46,90,118,53,25,109,65,133,169,221,241,72,100,16,60,248,212,160,140,38,10,126,82,150,186,206,226,91,119,3,47,235,199,179,159,220,240,132,168,108,64,52,24,161,141,249,213,17,61,73,101,131,175,219,247,51,31,107,71,254,210,166,138,78,98,22,58,121,85,33,13,201,229,145,189,4,40,92,112,180,152,236,192,106,70,50,30,218,246,130,174,23,59,79,99,167,139,255,211,144,188,200,228,32,12,120,84,237,193,181,153,93,113,5,41,76,96,20,56,252,208,164,136,49,29,105,69,129,173,217,245,182,154,238,194,6,42,94,114,203,231,147,191,123,87,35,15,165,137,253,209,21,57,77,97,216,244,128,172,104,68,48,28,95,115,7,43,239,195,183,155,34,14,122,86,146,190,202,230,0,45,90,119,180,153,238,195,117,88,47,2,193,236,155,182,234,199,176,157,94,115,4,41,159,178,197,232,43,6,113,92,201,228,147,190,125,80,39,10,188,145,230,203,8,37,82,127,35,14,121,84,151,186,205,224,86,123,12,33,226,207,184,149,143,162,213,248,59,22,97,76,250,215,160,141,78,99,20,57,101,72,63,18,209,252,139,166,16,61,74,103,164,137,254,211,70,107,28,49,242,223,168,133,51,30,105,68,135,170,221,240,172,129,246,219,24,53,66,111,217,244,131,174,109,64,55,26,3,46,89,116,183,154,237,192,118,91,44,1,194,239,152,181,233,196,179,158,93,112,7,42,156,177,198,235,40,5,114,95,202,231,144,189,126,83,36,9,191,146,229,200,11,38,81,124,32,13,122,87,148,185,206,227,85,120,15,34,225,204,187,150,140,161,214,251,56,21,98,79,249,212,163,142,77,96,23,58,102,75,60,17,210,255,136,165,19,62,73,100,167,138,253,208,69,104,31,50,241,220,171,134,48,29,106,71,132,169,222,243,175,130,245,216,27,54,65,108,218,247,128,173,110,67,52,25,0,46,92,114,184,150,228,202,109,67,49,31,213,251,137,167,218,244,134,168,98,76,62,16,183,153,235,197,15,33,83,125,169,135,245,219,17,63,77,99,196,234,152,182,124,82,32,14,115,93,47,1,203,229,151,185,30,48,66,108,166,136,250,212,79,97,19,61,247,217,171,133,34,12,126,80,154,180,198,232,149,187,201,231,45,3,113,95,248,214,164,138,64,110,28,50,230,200,186,148,94,112,2,44,139,165,215,249,51,29,111,65,60,18,96,78,132,170,216,246,81,127,13,35,233,199,181,155,158,176,194,236,38,8,122,84,243,221,175,129,75,101,23,57,68,106,24,54,252,210,160,142,41,7,117,91,145,191,205,227,55,25,107,69,143,161,211,253,90,116,6,40,226,204,190,144,237,195,177,159,85,123,9,39,128,174,220,242,56,22,100,74,209,255,141,163,105,71,53,27,188,146,224,206,4,42,88,118,11,37,87,121,179,157,239,193,102,72,58,20,222,240,130,172,120,86,36,10,192,238,156,178,21,59,73,103,173,131,241,223,162,140,254,208,26,52,70,104,207,225,147,189,119,89,43,5,0,47,94,113,188,147,226,205,101,74,59,20,217,246,135,168,202,229,148,187,118,89,40,7,175,128,241,222,19,60,77,98,137,166,215,248,53,26,107,68,236,195,178,157,80,127,14,33,67,108,29,50,255,208,161,142,38,9,120,87,154,181,196,235,15,32,81,126,179,156,237,194,106,69,52,27,214,249,136,167,197,234,155,180,121,86,39,8,160,143,254,209,28,51,66,109,134,169,216,247,58,21,100,75,227,204,189,146,95,112,1,46,76,99,18,61,240,223,174,129,41,6,119,88,149,186,203,228,30,49,64,111,162,141,252,211,123,84,37,10,199,232,153,182,212,251,138,165,104,71,54,25,177,158,239,192,13,34,83,124,151,184,201,230,43,4,117,90,242,221,172,131,78,97,16,63,93,114,3,44,225,206,191,144,56,23,102,73,132,171,218,245,17,62,79,96,173,130,243,220,116,91,42,5,200,231,150,185,219,244,133,170,103,72,57,22,190,145,224,207,2,45,92,115,152,183,198,233,36,11,122,85,253,210,163,140,65,110,31,48,82,125,12,35,238,193,176,159,55,24,105,70,139,164,213,250,0,48,96,80,192,240,160,144,157,173,253,205,93,109,61,13,39,23,71,119,231,215,135,183,186,138,218,234,122,74,26,42,78,126,46,30,142,190,238,222,211,227,179,131,19,35,115,67,105,89,9,57,169,153,201,249,244,196,148,164,52,4,84,100,156,172,252,204,92,108,60,12,1,49,97,81,193,241,161,145,187,139,219,235,123,75,27,43,38,22,70,118,230,214,134,182,210,226,178,130,18,34,114,66,79,127,47,31,143,191,239,223,245,197,149,165,53,5,85,101,104,88,8,56,168,152,200,248,37,21,69,117,229,213,133,181,184,136,216,232,120,72,24,40,2,50,98,82,194,242,162,146,159,175,255,207,95,111,63,15,107,91,11,59,171,155,203,251,246,198,150,166,54,6,86,102,76,124,44,28,140,188,236,220,209,225,177,129,17,33,113,65,185,137,217,233,121,73,25,41,36,20,68,116,228,212,132,180,158,174,254,206,94,110,62,14,3,51,99,83,195,243,163,147,247,199,151,167,55,7,87,103,106,90,10,58,170,154,202,250,208,224,176,128,16,32,112,64,77,125,45,29,141,189,237,221,0,49,98,83,196,245,166,151,149,164,247,198,81,96,51,2,55,6,85,100,243,194,145,160,162,147,192,241,102,87,4,53,110,95,12,61,170,155,200,249,251,202,153,168,63,14,93,108,89,104,59,10,157,172,255,206,204,253,174,159,8,57,106,91,220,237,190,143,24,41,122,75,73,120,43,26,141,188,239,222,235,218,137,184,47,30,77,124,126,79,28,45,186,139,216,233,178,131,208,225,118,71,20,37,39,22,69,116,227,210,129,176,133,180,231,214,65,112,35,18,16,33,114,67,212,229,182,135,165,148,199,246,97,80,3,50,48,1,82,99,244,197,150,167,146,163,240,193,86,103,52,5,7,54,101,84,195,242,161,144,203,250,169,152,15,62,109,92,94,111,60,13,154,171,248,201,252,205,158,175,56,9,90,107,105,88,11,58,173,156,207,254,121,72,27,42,189,140,223,238,236,221,142,191,40,25,74,123,78,127,44,29,138,187,232,217,219,234,185,136,31,46,125,76,23,38,117,68,211,226,177,128,130,179,224,209,70,119,36,21,32,17,66,115,228,213,134,183,181,132,215,230,113,64,19,34,0,50,100,86,200,250,172,158,141,191,233,219,69,119,33,19,7,53,99,81,207,253,171,153,138,184,238,220,66,112,38,20,14,60,106,88,198,244,162,144,131,177,231,213,75,121,47,29,9,59,109,95,193,243,165,151,132,182,224,210,76,126,40,26,28,46,120,74,212,230,176,130,145,163,245,199,89,107,61,15,27,41,127,77,211,225,183,133,150,164,242,192,94,108,58,8,18,32,118,68,218,232,190,140,159,173,251,201,87,101,51,1,21,39,113,67,221,239,185,139,152,170,252,206,80,98,52,6,56,10,92,110,240,194,148,166,181,135,209,227,125,79,25,43,63,13,91,105,247,197,147,161,178,128,214,228,122,72,30,44,54,4,82,96,254,204,154,168,187,137,223,237,115,65,23,37,49,3,85,103,249,203,157,175,188,142,216,234,116,70,16,34,36,22,64,114,236,222,136,186,169,155,205,255,97,83,5,55,35,17,71,117,235,217,143,189,174,156,202,248,102,84,2,48,42,24,78,124,226,208,134,180,167,149,195,241,111,93,11,57,45,31,73,123,229,215,129,179,160,146,196,246,104,90,12,62,0,51,102,85,204,255,170,153,133,182,227,208,73,122,47,28,23,36,113,66,219,232,189,142,146,161,244,199,94,109,56,11,46,29,72,123,226,209,132,183,171,152,205,254,103,84,1,50,57,10,95,108,245,198,147,160,188,143,218,233,112,67,22,37,92,111,58,9,144,163,246,197,217,234,191,140,21,38,115,64,75,120,45,30,135,180,225,210,206,253,168,155,2,49,100,87,114,65,20,39,190,141,216,235,247,196,145,162,59,8,93,110,101,86,3,48,169,154,207,252,224,211,134,181,44,31,74,121,184,139,222,237,116,71,18,33,61,14,91,104,241,194,151,164,175,156,201,250,99,80,5,54,42,25,76,127,230,213,128,179,150,165,240,195,90,105,60,15,19,32,117,70,223,236,185,138,129,178,231,212,77,126,43,24,4,55,98,81,200,251,174,157,228,215,130,177,40,27,78,125,97,82,7,52,173,158,203,248,243,192,149,166,63,12,89,106,118,69,16,35,186,137,220,239,202,249,172,159,6,53,96,83,79,124,41,26,131,176,229,214,221,238,187,136,17,34,119,68,88,107,62,13,148,167,242,193,0,52,104,92,208,228,184,140,189,137,213,225,109,89,5,49,103,83,15,59,183,131,223,235,218,238,178,134,10,62,98,86,206,250,166,146,30,42,118,66,115,71,27,47,163,151,203,255,169,157,193,245,121,77,17,37,20,32,124,72,196,240,172,152,129,181,233,221,81,101,57,13,60,8,84,96,236,216,132,176,230,210,142,186,54,2,94,106,91,111,51,7,139,191,227,215,79,123,39,19,159,171,247,195,242,198,154,174,34,22,74,126,40,28,64,116,248,204,144,164,149,161,253,201,69,113,45,25,31,43,119,67,207,251,167,147,162,150,202,254,114,70,26,46,120,76,16,36,168,156,192,244,197,241,173,153,21,33,125,73,209,229,185,141,1,53,105,93,108,88,4,48,188,136,212,224,182,130,222,234,102,82,14,58,11,63,99,87,219,239,179,135,158,170,246,194,78,122,38,18,35,23,75,127,243,199,155,175,249,205,145,165,41,29,65,117,68,112,44,24,148,160,252,200,80,100,56,12,128,180,232,220,237,217,133,177,61,9,85,97,55,3,95,107,231,211,143,187,138,190,226,214,90,110,50,6,0,53,106,95,212,225,190,139,181,128,223,234,97,84,11,62,119,66,29,40,163,150,201,252,194,247,168,157,22,35,124,73,238,219,132,177,58,15,80,101,91,110,49,4,143,186,229,208,153,172,243,198,77,120,39,18,44,25,70,115,248,205,146,167,193,244,171,158,21,32,127,74,116,65,30,43,160,149,202,255,182,131,220,233,98,87,8,61,3,54,105,92,215,226,189,136,47,26,69,112,251,206,145,164,154,175,240,197,78,123,36,17,88,109,50,7,140,185,230,211,237,216,135,178,57,12,83,102,159,170,245,192,75,126,33,20,42,31,64,117,254,203,148,161,232,221,130,183,60,9,86,99,93,104,55,2,137,188,227,214,113,68,27,46,165,144,207,250,196,241,174,155,16,37,122,79,6,51,108,89,210,231,184,141,179,134,217,236,103,82,13,56,94,107,52,1,138,191,224,213,235,222,129,180,63,10,85,96,41,28,67,118,253,200,151,162,156,169,246,195,72,125,34,23,176,133,218,239,100,81,14,59,5,48,111,90,209,228,187,142,199,242,173,152,19,38,121,76,114,71,24,45,166,147,204,249,0,54,108,90,216,238,180,130,173,155,193,247,117,67,25,47,71,113,43,29,159,169,243,197,234,220,134,176,50,4,94,104,142,184,226,212,86,96,58,12,35,21,79,121,251,205,151,161,201,255,165,147,17,39,125,75,100,82,8,62,188,138,208,230,1,55,109,91,217,239,181,131,172,154,192,246,116,66,24,46,70,112,42,28,158,168,242,196,235,221,135,177,51,5,95,105,143,185,227,213,87,97,59,13,34,20,78,120,250,204,150,160,200,254,164,146,16,38,124,74,101,83,9,63,189,139,209,231,2,52,110,88,218,236,182,128,175,153,195,245,119,65,27,45,69,115,41,31,157,171,241,199,232,222,132,178,48,6,92,106,140,186,224,214,84,98,56,14,33,23,77,123,249,207,149,163,203,253,167,145,19,37,127,73,102,80,10,60,190,136,210,228,3,53,111,89,219,237,183,129,174,152,194,244,118,64,26,44,68,114,40,30,156,170,240,198,233,223,133,179,49,7,93,107,141,187,225,215,85,99,57,15,32,22,76,122,248,206,148,162,202,252,166,144,18,36,126,72,103,81,11,61,191,137,211,229,0,55,110,89,220,235,178,133,165,146,203,252,121,78,23,32,87,96,57,14,139,188,229,210,242,197,156,171,46,25,64,119,174,153,192,247,114,69,28,43,11,60,101,82,215,224,185,142,249,206,151,160,37,18,75,124,92,107,50,5,128,183,238,217,65,118,47,24,157,170,243,196,228,211,138,189,56,15,86,97,22,33,120,79,202,253,164,147,179,132,221,234,111,88,1,54,239,216,129,182,51,4,93,106,74,125,36,19,150,161,248,207,184,143,214,225,100,83,10,61,29,42,115,68,193,246,175,152,130,181,236,219,94,105,48,7,39,16,73,126,251,204,149,162,213,226,187,140,9,62,103,80,112,71,30,41,172,155,194,245,44,27,66,117,240,199,158,169,137,190,231,208,85,98,59,12,123,76,21,34,167,144,201,254,222,233,176,135,2,53,108,91,195,244,173,154,31,40,113,70,102,81,8,63,186,141,212,227,148,163,250,205,72,127,38,17,49,6,95,104,237,218,131,180,109,90,3,52,177,134,223,232,200,255,166,145,20,35,122,77,58,13,84,99,230,209,136,191,159,168,241,198,67,116,45,26,0,56,112,72,224,216,144,168,221,229,173,149,61,5,77,117,167,159,215,239,71,127,55,15,122,66,10,50,154,162,234,210,83,107,35,27,179,139,195,251,142,182,254,198,110,86,30,38,244,204,132,188,20,44,100,92,41,17,89,97,201,241,185,129,166,158,214,238,70,126,54,14,123,67,11,51,155,163,235,211,1,57,113,73,225,217,145,169,220,228,172,148,60,4,76,116,245,205,133,189,21,45,101,93,40,16,88,96,200,240,184,128,82,106,34,26,178,138,194,250,143,183,255,199,111,87,31,39,81,105,33,25,177,137,193,249,140,180,252,196,108,84,28,36,246,206,134,190,22,46,102,94,43,19,91,99,203,243,187,131,2,58,114,74,226,218,146,170,223,231,175,151,63,7,79,119,165,157,213,237,69,125,53,13,120,64,8,48,152,160,232,208,247,207,135,191,23,47,103,95,42,18,90,98,202,242,186,130,80,104,32,24,176,136,192,248,141,181,253,197,109,85,29,37,164,156,212,236,68,124,52,12,121,65,9,49,153,161,233,209,3,59,115,75,227,219,147,171,222,230,174,150,62,6,78,118,0,57,114,75,228,221,150,175,213,236,167,158,49,8,67,122,183,142,197,252,83,106,33,24,98,91,16,41,134,191,244,205,115,74,1,56,151,174,229,220,166,159,212,237,66,123,48,9,196,253,182,143,32,25,82,107,17,40,99,90,245,204,135,190,230,223,148,173,2,59,112,73,51,10,65,120,215,238,165,156,81,104,35,26,181,140,199,254,132,189,246,207,96,89,18,43,149,172,231,222,113,72,3,58,64,121,50,11,164,157,214,239,34,27,80,105,198,255,180,141,247,206,133,188,19,42,97,88,209,232,163,154,53,12,71,126,4,61,118,79,224,217,146,171,102,95,20,45,130,187,240,201,179,138,193,248,87,110,37,28,162,155,208,233,70,127,52,13,119,78,5,60,147,170,225,216,21,44,103,94,241,200,131,186,192,249,178,139,36,29,86,111,55,14,69,124,211,234,161,152,226,219,144,169,6,63,116,77,128,185,242,203,100,93,22,47,85,108,39,30,177,136,195,250,68,125,54,15,160,153,210,235,145,168,227,218,117,76,7,62,243,202,129,184,23,46,101,92,38,31,84,109,194,251,176,137,0,58,116,78,232,210,156,166,205,247,185,131,37,31,81,107,135,189,243,201,111,85,27,33,74,112,62,4,162,152,214,236,19,41,103,93,251,193,143,181,222,228,170,144,54,12,66,120,148,174,224,218,124,70,8,50,89,99,45,23,177,139,197,255,38,28,82,104,206,244,186,128,235,209,159,165,3,57,119,77,161,155,213,239,73,115,61,7,108,86,24,34,132,190,240,202,53,15,65,123,221,231,169,147,248,194,140,182,16,42,100,94,178,136,198,252,90,96,46,20,127,69,11,49,151,173,227,217,76,118,56,2,164,158,208,234,129,187,245,207,105,83,29,39,203,241,191,133,35,25,87,109,6,60,114,72,238,212,154,160,95,101,43,17,183,141,195,249,146,168,230,220,122,64,14,52,216,226,172,150,48,10,68,126,21,47,97,91,253,199,137,179,106,80,30,36,130,184,246,204,167,157,211,233,79,117,59,1,237,215,153,163,5,63,113,75,32,26,84,110,200,242,188,134,121,67,13,55,145,171,229,223,180,142,192,250,92,102,40,18,254,196,138,176,22,44,98,88,51,9,71,125,219,225,175,149,0,59,118,77,236,215,154,161,197,254,179,136,41,18,95,100,151,172,225,218,123,64,13,54,82,105,36,31,190,133,200,243,51,8,69,126,223,228,169,146,246,205,128,187,26,33,108,87,164,159,210,233,72,115,62,5,97,90,23,44,141,182,251,192,102,93,16,43,138,177,252,199,163,152,213,238,79,116,57,2,241,202,135,188,29,38,107,80,52,15,66,121,216,227,174,149,85,110,35,24,185,130,207,244,144,171,230,221,124,71,10,49,194,249,180,143,46,21,88,99,7,60,113,74,235,208,157,166,204,247,186,129,32,27,86,109,9,50,127,68,229,222,147,168,91,96,45,22,183,140,193,250,158,165,232,211,114,73,4,63,255,196,137,178,19,40,101,94,58,1,76,119,214,237,160,155,104,83,30,37,132,191,242,201,173,150,219,224,65,122,55,12,170,145,220,231,70,125,48,11,111,84,25,34,131,184,245,206,61,6,75,112,209,234,167,156,248,195,142,181,20,47,98,89,153,162,239,212,117,78,3,56,92,103,42,17,176,139,198,253,14,53,120,67,226,217,148,175,203,240,189,134,39,28,81,106,0,60,120,68,240,204,136,180,253,193,133,185,13,49,117,73,231,219,159,163,23,43,111,83,26,38,98,94,234,214,146,174,211,239,171,151,35,31,91,103,46,18,86,106,222,226,166,154,52,8,76,112,196,248,188,128,201,245,177,141,57,5,65,125,187,135,195,255,75,119,51,15,70,122,62,2,182,138,206,242,92,96,36,24,172,144,212,232,161,157,217,229,81,109,41,21,104,84,16,44,152,164,224,220,149,169,237,209,101,89,29,33,143,179,247,203,127,67,7,59,114,78,10,54,130,190,250,198,107,87,19,47,155,167,227,223,150,170,238,210,102,90,30,34,140,176,244,200,124,64,4,56,113,77,9,53,129,189,249,197,184,132,192,252,72,116,48,12,69,121,61,1,181,137,205,241,95,99,39,27,175,147,215,235,162,158,218,230,82,110,42,22,208,236,168,148,32,28,88,100,45,17,85,105,221,225,165,153,55,11,79,115,199,251,191,131,202,246,178,142,58,6,66,126,3,63,123,71,243,207,139,183,254,194,134,186,14,50,118,74,228,216,156,160,20,40,108,80,25,37,97,93,233,213,145,173,0,61,122,71,244,201,142,179,245,200,143,178,1,60,123,70,247,202,141,176,3,62,121,68,2,63,120,69,246,203,140,177,243,206,137,180,7,58,125,64,6,59,124,65,242,207,136,181,4,57,126,67,240,205,138,183,241,204,139,182,5,56,127,66,251,198,129,188,15,50,117,72,14,51,116,73,250,199,128,189,12,49,118,75,248,197,130,191,249,196,131,190,13,48,119,74,8,53,114,79,252,193,134,187,253,192,135,186,9,52,115,78,255,194,133,184,11,54,113,76,10,55,112,77,254,195,132,185,235,214,145,172,31,34,101,88,30,35,100,89,234,215,144,173,28,33,102,91,232,213,146,175,233,212,147,174,29,32,103,90,24,37,98,95,236,209,150,171,237,208,151,170,25,36,99,94,239,210,149,168,27,38,97,92,26,39,96,93,238,211,148,169,16,45,106,87,228,217,158,163,229,216,159,162,17,44,107,86,231,218,157,160,19,46,105,84,18,47,104,85,230,219,156,161,227,222,153,164,23,42,109,80,22,43,108,81,226,223,152,165,20,41,110,83,224,221,154,167,225,220,155,166,21,40,111,82,0,62,124,66,248,198,132,186,237,211,145,175,21,43,105,87,199,249,187,133,63,1,67,125,42,20,86,104,210,236,174,144,147,173,239,209,107,85,23,41,126,64,2,60,134,184,250,196,84,106,40,22,172,146,208,238,185,135,197,251,65,127,61,3,59,5,71,121,195,253,191,129,214,232,170,148,46,16,82,108,252,194,128,190,4,58,120,70,17,47,109,83,233,215,149,171,168,150,212,234,80,110,44,18,69,123,57,7,189,131,193,255,111,81,19,45,151,169,235,213,130,188,254,192,122,68,6,56,118,72,10,52,142,176,242,204,155,165,231,217,99,93,31,33,177,143,205,243,73,119,53,11,92,98,32,30,164,154,216,230,229,219,153,167,29,35,97,95,8,54,116,74,240,206,140,178,34,28,94,96,218,228,166,152,207,241,179,141,55,9,75,117,77,115,49,15,181,139,201,247,160,158,220,226,88,102,36,26,138,180,246,200,114,76,14,48,103,89,27,37,159,161,227,221,222,224,162,156,38,24,90,100,51,13,79,113,203,245,183,137,25,39,101,91,225,223,157,163,244,202,136,182,12,50,112,78,0,63,126,65,252,195,130,189,229,218,155,164,25,38,103,88,215,232,169,150,43,20,85,106,50,13,76,115,206,241,176,143,179,140,205,242,79,112,49,14,86,105,40,23,170,149,212,235,100,91,26,37,152,167,230,217,129,190,255,192,125,66,3,60,123,68,5,58,135,184,249,198,158,161,224,223,98,93,28,35,172,147,210,237,80,111,46,17,73,118,55,8,181,138,203,244,200,247,182,137,52,11,74,117,45,18,83,108,209,238,175,144,31,32,97,94,227,220,157,162,250,197,132,187,6,57,120,71,246,201,136,183,10,53,116,75,19,44,109,82,239,208,145,174,33,30,95,96,221,226,163,156,196,251,186,133,56,7,70,121,69,122,59,4,185,134,199,248,160,159,222,225,92,99,34,29,146,173,236,211,110,81,16,47,119,72,9,54,139,180,245,202,141,178,243,204,113,78,15,48,104,87,22,41,148,171,234,213,90,101,36,27,166,153,216,231,191,128,193,254,67,124,61,2,62,1,64,127,194,253,188,131,219,228,165,154,39,24,89,102,233,214,151,168,21,42,107,84,12,51,114,77,240,207,142,177,0,64,128,192,29,93,157,221,58,122,186,250,39,103,167,231,116,52,244,180,105,41,233,169,78,14,206,142,83,19,211,147,232,168,104,40,245,181,117,53,210,146,82,18,207,143,79,15,156,220,28,92,129,193,1,65,166,230,38,102,187,251,59,123,205,141,77,13,208,144,80,16,247,183,119,55,234,170,106,42,185,249,57,121,164,228,36,100,131,195,3,67,158,222,30,94,37,101,165,229,56,120,184,248,31,95,159,223,2,66,130,194,81,17,209,145,76,12,204,140,107,43,235,171,118,54,246,182,135,199,7,71,154,218,26,90,189,253,61,125,160,224,32,96,243,179,115,51,238,174,110,46,201,137,73,9,212,148,84,20,111,47,239,175,114,50,242,178,85,21,213,149,72,8,200,136,27,91,155,219,6,70,134,198,33,97,161,225,60,124,188,252,74,10,202,138,87,23,215,151,112,48,240,176,109,45,237,173,62,126,190,254,35,99,163,227,4,68,132,196,25,89,153,217,162,226,34,98,191,255,63,127,152,216,24,88,133,197,5,69,214,150,86,22,203,139,75,11,236,172,108,44,241,177,113,49,0,65,130,195,25,88,155,218,50,115,176,241,43,106,169,232,100,37,230,167,125,60,255,190,86,23,212,149,79,14,205,140,200,137,74,11,209,144,83,18,250,187,120,57,227,162,97,32,172,237,46,111,181,244,55,118,158,223,28,93,135,198,5,68,141,204,15,78,148,213,22,87,191,254,61,124,166,231,36,101,233,168,107,42,240,177,114,51,219,154,89,24,194,131,64,1,69,4,199,134,92,29,222,159,119,54,245,180,110,47,236,173,33,96,163,226,56,121,186,251,19,82,145,208,10,75,136,201,7,70,133,196,30,95,156,221,53,116,183,246,44,109,174,239,99,34,225,160,122,59,248,185,81,16,211,146,72,9,202,139,207,142,77,12,214,151,84,21,253,188,127,62,228,165,102,39,171,234,41,104,178,243,48,113,153,216,27,90,128,193,2,67,138,203,8,73,147,210,17,80,184,249,58,123,161,224,35,98,238,175,108,45,247,182,117,52,220,157,94,31,197,132,71,6,66,3,192,129,91,26,217,152,112,49,242,179,105,40,235,170,38,103,164,229,63,126,189,252,20,85,150,215,13,76,143,206,0,66,132,198,21,87,145,211,42,104,174,236,63,125,187,249,84,22,208,146,65,3,197,135,126,60,250,184,107,41,239,173,168,234,44,110,189,255,57,123,130,192,6,68,151,213,19,81,252,190,120,58,233,171,109,47,214,148,82,16,195,129,71,5,77,15,201,139,88,26,220,158,103,37,227,161,114,48,246,180,25,91,157,223,12,78,136,202,51,113,183,245,38,100,162,224,229,167,97,35,240,178,116,54,207,141,75,9,218,152,94,28,177,243,53,119,164,230,32,98,155,217,31,93,142,204,10,72,154,216,30,92,143,205,11,73,176,242,52,118,165,231,33,99,206,140,74,8,219,153,95,29,228,166,96,34,241,179,117,55,50,112,182,244,39,101,163,225,24,90,156,222,13,79,137,203,102,36,226,160,115,49,247,181,76,14,200,138,89,27,221,159,215,149,83,17,194,128,70,4,253,191,121,59,232,170,108,46,131,193,7,69,150,212,18,80,169,235,45,111,188,254,56,122,127,61,251,185,106,40,238,172,85,23,209,147,64,2,196,134,43,105,175,237,62,124,186,248,1,67,133,199,20,86,144,210,0,67,134,197,17,82,151,212,34,97,164,231,51,112,181,246,68,7,194,129,85,22,211,144,102,37,224,163,119,52,241,178,136,203,14,77,153,218,31,92,170,233,44,111,187,248,61,126,204,143,74,9,221,158,91,24,238,173,104,43,255,188,121,58,13,78,139,200,28,95,154,217,47,108,169,234,62,125,184,251,73,10,207,140,88,27,222,157,107,40,237,174,122,57,252,191,133,198,3,64,148,215,18,81,167,228,33,98,182,245,48,115,193,130,71,4,208,147,86,21,227,160,101,38,242,177,116,55,26,89,156,223,11,72,141,206,56,123,190,253,41,106,175,236,94,29,216,155,79,12,201,138,124,63,250,185,109,46,235,168,146,209,20,87,131,192,5,70,176,243,54,117,161,226,39,100,214,149,80,19,199,132,65,2,244,183,114,49,229,166,99,32,23,84,145,210,6,69,128,195,53,118,179,240,36,103,162,225,83,16,213,150,66,1,196,135,113,50,247,180,96,35,230,165,159,220,25,90,142,205,8,75,189,254,59,120,172,239,42,105,219,152,93,30,202,137,76,15,249,186,127,60,232,171,110,45,0,68,136,204,13,73,133,193,26,94,146,214,23,83,159,219,52,112,188,248,57,125,177,245,46,106,166,226,35,103,171,239,104,44,224,164,101,33,237,169,114,54,250,190,127,59,247,179,92,24,212,144,81,21,217,157,70,2,206,138,75,15,195,135,208,148,88,28,221,153,85,17,202,142,66,6,199,131,79,11,228,160,108,40,233,173,97,37,254,186,118,50,243,183,123,63,184,252,48,116,181,241,61,121,162,230,42,110,175,235,39,99,140,200,4,64,129,197,9,77,150,210,30,90,155,223,19,87,189,249,53,113,176,244,56,124,167,227,47,107,170,238,34,102,137,205,1,69,132,192,12,72,147,215,27,95,158,218,22,82,213,145,93,25,216,156,80,20,207,139,71,3,194,134,74,14,225,165,105,45,236,168,100,32,251,191,115,55,246,178,126,58,109,41,229,161,96,36,232,172,119,51,255,187,122,62,242,182,89,29,209,149,84,16,220,152,67,7,203,143,78,10,198,130,5,65,141,201,8,76,128,196,31,91,151,211,18,86,154,222,49,117,185,253,60,120,180,240,43,111,163,231,38,98,174,234,0,69,138,207,9,76,131,198,18,87,152,221,27,94,145,212,36,97,174,235,45,104,167,226,54,115,188,249,63,122,181,240,72,13,194,135,65,4,203,142,90,31,208,149,83,22,217,156,108,41,230,163,101,32,239,170,126,59,244,177,119,50,253,184,144,213,26,95,153,220,19,86,130,199,8,77,139,206,1,68,180,241,62,123,189,248,55,114,166,227,44,105,175,234,37,96,216,157,82,23,209,148,91,30,202,143,64,5,195,134,73,12,252,185,118,51,245,176,127,58,238,171,100,33,231,162,109,40,61,120,183,242,52,113,190,251,47,106,165,224,38,99,172,233,25,92,147,214,16,85,154,223,11,78,129,196,2,71,136,205,117,48,255,186,124,57,246,179,103,34,237,168,110,43,228,161,81,20,219,158,88,29,210,151,67,6,201,140,74,15,192,133,173,232,39,98,164,225,46,107,191,250,53,112,182,243,60,121,137,204,3,70,128,197,10,79,155,222,17,84,146,215,24,93,229,160,111,42,236,169,102,35,247,178,125,56,254,187,116,49,193,132,75,14,200,141,66,7,211,150,89,28,218,159,80,21,0,70,140,202,5,67,137,207,10,76,134,192,15,73,131,197,20,82,152,222,17,87,157,219,30,88,146,212,27,93,151,209,40,110,164,226,45,107,161,231,34,100,174,232,39,97,171,237,60,122,176,246,57,127,181,243,54,112,186,252,51,117,191,249,80,22,220,154,85,19,217,159,90,28,214,144,95,25,211,149,68,2,200,142,65,7,205,139,78,8,194,132,75,13,199,129,120,62,244,178,125,59,241,183,114,52,254,184,119,49,251,189,108,42,224,166,105,47,229,163,102,32,234,172,99,37,239,169,160,230,44,106,165,227,41,111,170,236,38,96,175,233,35,101,180,242,56,126,177,247,61,123,190,248,50,116,187,253,55,113,136,206,4,66,141,203,1,71,130,196,14,72,135,193,11,77,156,218,16,86,153,223,21,83,150,208,26,92,147,213,31,89,240,182,124,58,245,179,121,63,250,188,118,48,255,185,115,53,228,162,104,46,225,167,109,43,238,168,98,36,235,173,103,33,216,158,84,18,221,155,81,23,210,148,94,24,215,145,91,29,204,138,64,6,201,143,69,3,198,128,74,12,195,133,79,9,0,71,142,201,1,70,143,200,2,69,140,203,3,68,141,202,4,67,138,205,5,66,139,204,6,65,136,207,7,64,137,206,8,79,134,193,9,78,135,192,10,77,132,195,11,76,133,194,12,75,130,197,13,74,131,196,14,73,128,199,15,72,129,198,16,87,158,217,17,86,159,216,18,85,156,219,19,84,157,218,20,83,154,221,21,82,155,220,22,81,152,223,23,80,153,222,24,95,150,209,25,94,151,208,26,93,148,211,27,92,149,210,28,91,146,213,29,90,147,212,30,89,144,215,31,88,145,214,32,103,174,233,33,102,175,232,34,101,172,235,35,100,173,234,36,99,170,237,37,98,171,236,38,97,168,239,39,96,169,238,40,111,166,225,41,110,167,224,42,109,164,227,43,108,165,226,44,107,162,229,45,106,163,228,46,105,160,231,47,104,161,230,48,119,190,249,49,118,191,248,50,117,188,251,51,116,189,250,52,115,186,253,53,114,187,252,54,113,184,255,55,112,185,254,56,127,182,241,57,126,183,240,58,125,180,243,59,124,181,242,60,123,178,245,61,122,179,244,62,121,176,247,63,120,177,246,0,72,144,216,61,117,173,229,122,50,234,162,71,15,215,159,244,188,100,44,201,129,89,17,142,198,30,86,179,251,35,107,245,189,101,45,200,128,88,16,143,199,31,87,178,250,34,106,1,73,145,217,60,116,172,228,123,51,235,163,70,14,214,158,247,191,103,47,202,130,90,18,141,197,29,85,176,248,32,104,3,75,147,219,62,118,174,230,121,49,233,161,68,12,212,156,2,74,146,218,63,119,175,231,120,48,232,160,69,13,213,157,246,190,102,46,203,131,91,19,140,196,28,84,177,249,33,105,243,187,99,43,206,134,94,22,137,193,25,81,180,252,36,108,7,79,151,223,58,114,170,226,125,53,237,165,64,8,208,152,6,78,150,222,59,115,171,227,124,52,236,164,65,9,209,153,242,186,98,42,207,135,95,23,136,192,24,80,181,253,37,109,4,76,148,220,57,113,169,225,126,54,238,166,67,11,211,155,240,184,96,40,205,133,93,21,138,194,26,82,183,255,39,111,241,185,97,41,204,132,92,20,139,195,27,83,182,254,38,110,5,77,149,221,56,112,168,224,127,55,239,167,66,10,210,154,0,73,146,219,57,112,171,226,114,59,224,169,75,2,217,144,228,173,118,63,221,148,79,6,150,223,4,77,175,230,61,116,213,156,71,14,236,165,126,55,167,238,53,124,158,215,12,69,49,120,163,234,8,65,154,211,67,10,209,152,122,51,232,161,183,254,37,108,142,199,28,85,197,140,87,30,252,181,110,39,83,26,193,136,106,35,248,177,33,104,179,250,24,81,138,195,98,43,240,185,91,18,201,128,16,89,130,203,41,96,187,242,134,207,20,93,191,246,45,100,244,189,102,47,205,132,95,22,115,58,225,168,74,3,216,145,1,72,147,218,56,113,170,227,151,222,5,76,174,231,60,117,229,172,119,62,220,149,78,7,166,239,52,125,159,214,13,68,212,157,70,15,237,164,127,54,66,11,208,153,123,50,233,160,48,121,162,235,9,64,155,210,196,141,86,31,253,180,111,38,182,255,36,109,143,198,29,84,32,105,178,251,25,80,139,194,82,27,192,137,107,34,249,176,17,88,131,202,40,97,186,243,99,42,241,184,90,19,200,129,245,188,103,46,204,133,94,23,135,206,21,92,190,247,44,101,0,74,148,222,53,127,161,235,106,32,254,180,95,21,203,129,212,158,64,10,225,171,117,63,190,244,42,96,139,193,31,85,181,255,33,107,128,202,20,94,223,149,75,1,234,160,126,52,97,43,245,191,84,30,192,138,11,65,159,213,62,116,170,224,119,61,227,169,66,8,214,156,29,87,137,195,40,98,188,246,163,233,55,125,150,220,2,72,201,131,93,23,252,182,104,34,194,136,86,28,247,189,99,41,168,226,60,118,157,215,9,67,22,92,130,200,35,105,183,253,124,54,232,162,73,3,221,151,238,164,122,48,219,145,79,5,132,206,16,90,177,251,37,111,58,112,174,228,15,69,155,209,80,26,196,142,101,47,241,187,91,17,207,133,110,36,250,176,49,123,165,239,4,78,144,218,143,197,27,81,186,240,46,100,229,175,113,59,208,154,68,14,153,211,13,71,172,230,56,114,243,185,103,45,198,140,82,24,77,7,217,147,120,50,236,166,39,109,179,249,18,88,134,204,44,102,184,242,25,83,141,199,70,12,210,152,115,57,231,173,248,178,108,38,205,135,89,19,146,216,6,76,167,237,51,121,0,75,150,221,49,122,167,236,98,41,244,191,83,24,197,142,196,143,82,25,245,190,99,40,166,237,48,123,151,220,1,74,149,222,3,72,164,239,50,121,247,188,97,42,198,141,80,27,81,26,199,140,96,43,246,189,51,120,165,238,2,73,148,223,55,124,161,234,6,77,144,219,85,30,195,136,100,47,242,185,243,184,101,46,194,137,84,31,145,218,7,76,160,235,54,125,162,233,52,127,147,216,5,78,192,139,86,29,241,186,103,44,102,45,240,187,87,28,193,138,4,79,146,217,53,126,163,232,110,37,248,179,95,20,201,130,12,71,154,209,61,118,171,224,170,225,60,119,155,208,13,70,200,131,94,21,249,178,111,36,251,176,109,38,202,129,92,23,153,210,15,68,168,227,62,117,63,116,169,226,14,69,152,211,93,22,203,128,108,39,250,177,89,18,207,132,104,35,254,181,59,112,173,230,10,65,156,215,157,214,11,64,172,231,58,113,255,180,105,34,206,133,88,19,204,135,90,17,253,182,107,32,174,229,56,115,159,212,9,66,8,67,158,213,57,114,175,228,106,33,252,183,91,16,205,134,0,76,152,212,45,97,181,249,90,22,194,142,119,59,239,163,180,248,44,96,153,213,1,77,238,162,118,58,195,143,91,23,117,57,237,161,88,20,192,140,47,99,183,251,2,78,154,214,193,141,89,21,236,160,116,56,155,215,3,79,182,250,46,98,234,166,114,62,199,139,95,19,176,252,40,100,157,209,5,73,94,18,198,138,115,63,235,167,4,72,156,208,41,101,177,253,159,211,7,75,178,254,42,102,197,137,93,17,232,164,112,60,43,103,179,255,6,74,158,210,113,61,233,165,92,16,196,136,201,133,81,29,228,168,124,48,147,223,11,71,190,242,38,106,125,49,229,169,80,28,200,132,39,107,191,243,10,70,146,222,188,240,36,104,145,221,9,69,230,170,126,50,203,135,83,31,8,68,144,220,37,105,189,241,82,30,202,134,127,51,231,171,35,111,187,247,14,66,150,218,121,53,225,173,84,24,204,128,151,219,15,67,186,246,34,110,205,129,85,25,224,172,120,52,86,26,206,130,123,55,227,175,12,64,148,216,33,109,185,245,226,174,122,54,207,131,87,27,184,244,32,108,149,217,13,65,0,77,154,215,41,100,179,254,82,31,200,133,123,54,225,172,164,233,62,115,141,192,23,90,246,187,108,33,223,146,69,8,85,24,207,130,124,49,230,171,7,74,157,208,46,99,180,249,241,188,107,38,216,149,66,15,163,238,57,116,138,199,16,93,170,231,48,125,131,206,25,84,248,181,98,47,209,156,75,6,14,67,148,217,39,106,189,240,92,17,198,139,117,56,239,162,255,178,101,40,214,155,76,1,173,224,55,122,132,201,30,83,91,22,193,140,114,63,232,165,9,68,147,222,32,109,186,247,73,4,211,158,96,45,250,183,27,86,129,204,50,127,168,229,237,160,119,58,196,137,94,19,191,242,37,104,150,219,12,65,28,81,134,203,53,120,175,226,78,3,212,153,103,42,253,176,184,245,34,111,145,220,11,70,234,167,112,61,195,142,89,20,227,174,121,52,202,135,80,29,177,252,43,102,152,213,2,79,71,10,221,144,110,35,244,185,21,88,143,194,60,113,166,235,182,251,44,97,159,210,5,72,228,169,126,51,205,128,87,26,18,95,136,197,59,118,161,236,64,13,218,151,105,36,243,190,0,78,156,210,37,107,185,247,74,4,214,152,111,33,243,189,148,218,8,70,177,255,45,99,222,144,66,12,251,181,103,41,53,123,169,231,16,94,140,194,127,49,227,173,90,20,198,136,161,239,61,115,132,202,24,86,235,165,119,57,206,128,82,28,106,36,246,184,79,1,211,157,32,110,188,242,5,75,153,215,254,176,98,44,219,149,71,9,180,250,40,102,145,223,13,67,95,17,195,141,122,52,230,168,21,91,137,199,48,126,172,226,203,133,87,25,238,160,114,60,129,207,29,83,164,234,56,118,212,154,72,6,241,191,109,35,158,208,2,76,187,245,39,105,64,14,220,146,101,43,249,183,10,68,150,216,47,97,179,253,225,175,125,51,196,138,88,22,171,229,55,121,142,192,18,92,117,59,233,167,80,30,204,130,63,113,163,237,26,84,134,200,190,240,34,108,155,213,7,73,244,186,104,38,209,159,77,3,42,100,182,248,15,65,147,221,96,46,252,178,69,11,217,151,139,197,23,89,174,224,50,124,193,143,93,19,228,170,120,54,31,81,131,205,58,116,166,232,85,27,201,135,112,62,236,162,0,79,158,209,33,110,191,240,66,13,220,147,99,44,253,178,132,203,26,85,165,234,59,116,198,137,88,23,231,168,121,54,21,90,139,196,52,123,170,229,87,24,201,134,118,57,232,167,145,222,15,64,176,255,46,97,211,156,77,2,242,189,108,35,42,101,180,251,11,68,149,218,104,39,246,185,73,6,215,152,174,225,48,127,143,192,17,94,236,163,114,61,205,130,83,28,63,112,161,238,30,81,128,207,125,50,227,172,92,19,194,141,187,244,37,106,154,213,4,75,249,182,103,40,216,151,70,9,84,27,202,133,117,58,235,164,22,89,136,199,55,120,169,230,208,159,78,1,241,190,111,32,146,221,12,67,179,252,45,98,65,14,223,144,96,47,254,177,3,76,157,210,34,109,188,243,197,138,91,20,228,171,122,53,135,200,25,86,166,233,56,119,126,49,224,175,95,16,193,142,60,115,162,237,29,82,131,204,250,181,100,43,219,148,69,10,184,247,38,105,153,214,7,72,107,36,245,186,74,5,212,155,41,102,183,248,8,71,150,217,239,160,113,62,206,129,80,31,173,226,51,124,140,195,18,93,0,80,160,240,93,13,253,173,186,234,26,74,231,183,71,23,105,57,201,153,52,100,148,196,211,131,115,35,142,222,46,126,210,130,114,34,143,223,47,127,104,56,200,152,53,101,149,197,187,235,27,75,230,182,70,22,1,81,161,241,92,12,252,172,185,233,25,73,228,180,68,20,3,83,163,243,94,14,254,174,208,128,112,32,141,221,45,125,106,58,202,154,55,103,151,199,107,59,203,155,54,102,150,198,209,129,113,33,140,220,44,124,2,82,162,242,95,15,255,175,184,232,24,72,229,181,69,21,111,63,207,159,50,98,146,194,213,133,117,37,136,216,40,120,6,86,166,246,91,11,251,171,188,236,28,76,225,177,65,17,189,237,29,77,224,176,64,16,7,87,167,247,90,10,250,170,212,132,116,36,137,217,41,121,110,62,206,158,51,99,147,195,214,134,118,38,139,219,43,123,108,60,204,156,49,97,145,193,191,239,31,79,226,178,66,18,5,85,165,245,88,8,248,168,4,84,164,244,89,9,249,169,190,238,30,78,227,179,67,19,109,61,205,157,48,96,144,192,215,135,119,39,138,218,42,122,0,81,162,243,89,8,251,170,178,227,16,65,235,186,73,24,121,40,219,138,32,113,130,211,203,154,105,56,146,195,48,97,242,163,80,1,171,250,9,88,64,17,226,179,25,72,187,234,139,218,41,120,210,131,112,33,57,104,155,202,96,49,194,147,249,168,91,10,160,241,2,83,75,26,233,184,18,67,176,225,128,209,34,115,217,136,123,42,50,99,144,193,107,58,201,152,11,90,169,248,82,3,240,161,185,232,27,74,224,177,66,19,114,35,208,129,43,122,137,216,192,145,98,51,153,200,59,106,239,190,77,28,182,231,20,69,93,12,255,174,4,85,166,247,150,199,52,101,207,158,109,60,36,117,134,215,125,44,223,142,29,76,191,238,68,21,230,183,175,254,13,92,246,167,84,5,100,53,198,151,61,108,159,206,214,135,116,37,143,222,45,124,22,71,180,229,79,30,237,188,164,245,6,87,253,172,95,14,111,62,205,156,54,103,148,197,221,140,127,46,132,213,38,119,228,181,70,23,189,236,31,78,86,7,244,165,15,94,173,252,157,204,63,110,196,149,102,55,47,126,141,220,118,39,212,133,0,82,164,246,85,7,241,163,170,248,14,92,255,173,91,9,73,27,237,191,28,78,184,234,227,177,71,21,182,228,18,64,146,192,54,100,199,149,99,49,56,106,156,206,109,63,201,155,219,137,127,45,142,220,42,120,113,35,213,135,36,118,128,210,57,107,157,207,108,62,200,154,147,193,55,101,198,148,98,48,112,34,212,134,37,119,129,211,218,136,126,44,143,221,43,121,171,249,15,93,254,172,90,8,1,83,165,247,84,6,240,162,226,176,70,20,183,229,19,65,72,26,236,190,29,79,185,235,114,32,214,132,39,117,131,209,216,138,124,46,141,223,41,123,59,105,159,205,110,60,202,152,145,195,53,103,196,150,96,50,224,178,68,22,181,231,17,67,74,24,238,188,31,77,187,233,169,251,13,95,252,174,88,10,3,81,167,245,86,4,242,160,75,25,239,189,30,76,186,232,225,179,69,23,180,230,16,66,2,80,166,244,87,5,243,161,168,250,12,94,253,175,89,11,217,139,125,47,140,222,40,122,115,33,215,133,38,116,130,208,144,194,52,102,197,151,97,51,58,104,158,204,111,61,203,153,0,83,166,245,81,2,247,164,162,241,4,87,243,160,85,6,89,10,255,172,8,91,174,253,251,168,93,14,170,249,12,95,178,225,20,71,227,176,69,22,16,67,182,229,65,18,231,180,235,184,77,30,186,233,28,79,73,26,239,188,24,75,190,237,121,42,223,140,40,123,142,221,219,136,125,46,138,217,44,127,32,115,134,213,113,34,215,132,130,209,36,119,211,128,117,38,203,152,109,62,154,201,60,111,105,58,207,156,56,107,158,205,146,193,52,103,195,144,101,54,48,99,150,197,97,50,199,148,242,161,84,7,163,240,5,86,80,3,246,165,1,82,167,244,171,248,13,94,250,169,92,15,9,90,175,252,88,11,254,173,64,19,230,181,17,66,183,228,226,177,68,23,179,224,21,70,25,74,191,236,72,27,238,189,187,232,29,78,234,185,76,31,139,216,45,126,218,137,124,47,41,122,143,220,120,43,222,141,210,129,116,39,131,208,37,118,112,35,214,133,33,114,135,212,57,106,159,204,104,59,206,157,155,200,61,110,202,153,108,63,96,51,198,149,49,98,151,196,194,145,100,55,147,192,53,102,0,84,168,252,77,25,229,177,154,206,50,102,215,131,127,43,41,125,129,213,100,48,204,152,179,231,27,79,254,170,86,2,82,6,250,174,31,75,183,227,200,156,96,52,133,209,45,121,123,47,211,135,54,98,158,202,225,181,73,29,172,248,4,80,164,240,12,88,233,189,65,21,62,106,150,194,115,39,219,143,141,217,37,113,192,148,104,60,23,67,191,235,90,14,242,166,246,162,94,10,187,239,19,71,108,56,196,144,33,117,137,221,223,139,119,35,146,198,58,110,69,17,237,185,8,92,160,244,85,1,253,169,24,76,176,228,207,155,103,51,130,214,42,126,124,40,212,128,49,101,153,205,230,178,78,26,171,255,3,87,7,83,175,251,74,30,226,182,157,201,53,97,208,132,120,44,46,122,134,210,99,55,203,159,180,224,28,72,249,173,81,5,241,165,89,13,188,232,20,64,107,63,195,151,38,114,142,218,216,140,112,36,149,193,61,105,66,22,234,190,15,91,167,243,163,247,11,95,238,186,70,18,57,109,145,197,116,32,220,136,138,222,34,118,199,147,111,59,16,68,184,236,93,9,245,161,0,85,170,255,73,28,227,182,146,199,56,109,219,142,113,36,57,108,147,198,112,37,218,143,171,254,1,84,226,183,72,29,114,39,216,141,59,110,145,196,224,181,74,31,169,252,3,86,75,30,225,180,2,87,168,253,217,140,115,38,144,197,58,111,228,177,78,27,173,248,7,82,118,35,220,137,63,106,149,192,221,136,119,34,148,193,62,107,79,26,229,176,6,83,172,249,150,195,60,105,223,138,117,32,4,81,174,251,77,24,231,178,175,250,5,80,230,179,76,25,61,104,151,194,116,33,222,139,213,128,127,42,156,201,54,99,71,18,237,184,14,91,164,241,236,185,70,19,165,240,15,90,126,43,212,129,55,98,157,200,167,242,13,88,238,187,68,17,53,96,159,202,124,41,214,131,158,203,52,97,215,130,125,40,12,89,166,243,69,16,239,186,49,100,155,206,120,45,210,135,163,246,9,92,234,191,64,21,8,93,162,247,65,20,235,190,154,207,48,101,211,134,121,44,67,22,233,188,10,95,160,245,209,132,123,46,152,205,50,103,122,47,208,133,51,102,153,204,232,189,66,23,161,244,11,94,0,86,172,250,69,19,233,191,138,220,38,112,207,153,99,53,9,95,165,243,76,26,224,182,131,213,47,121,198,144,106,60,18,68,190,232,87,1,251,173,152,206,52,98,221,139,113,39,27,77,183,225,94,8,242,164,145,199,61,107,212,130,120,46,36,114,136,222,97,55,205,155,174,248,2,84,235,189,71,17,45,123,129,215,104,62,196,146,167,241,11,93,226,180,78,24,54,96,154,204,115,37,223,137,188,234,16,70,249,175,85,3,63,105,147,197,122,44,214,128,181,227,25,79,240,166,92,10,72,30,228,178,13,91,161,247,194,148,110,56,135,209,43,125,65,23,237,187,4,82,168,254,203,157,103,49,142,216,34,116,90,12,246,160,31,73,179,229,208,134,124,42,149,195,57,111,83,5,255,169,22,64,186,236,217,143,117,35,156,202,48,102,108,58,192,150,41,127,133,211,230,176,74,28,163,245,15,89,101,51,201,159,32,118,140,218,239,185,67,21,170,252,6,80,126,40,210,132,59,109,151,193,244,162,88,14,177,231,29,75,119,33,219,141,50,100,158,200,253,171,81,7,184,238,20,66,0,87,174,249,65,22,239,184,130,213,44,123,195,148,109,58,25,78,183,224,88,15,246,161,155,204,53,98,218,141,116,35,50,101,156,203,115,36,221,138,176,231,30,73,241,166,95,8,43,124,133,210,106,61,196,147,169,254,7,80,232,191,70,17,100,51,202,157,37,114,139,220,230,177,72,31,167,240,9,94,125,42,211,132,60,107,146,197,255,168,81,6,190,233,16,71,86,1,248,175,23,64,185,238,212,131,122,45,149,194,59,108,79,24,225,182,14,89,160,247,205,154,99,52,140,219,34,117,200,159,102,49,137,222,39,112,74,29,228,179,11,92,165,242,209,134,127,40,144,199,62,105,83,4,253,170,18,69,188,235,250,173,84,3,187,236,21,66,120,47,214,129,57,110,151,192,227,180,77,26,162,245,12,91,97,54,207,152,32,119,142,217,172,251,2,85,237,186,67,20,46,121,128,215,111,56,193,150,181,226,27,76,244,163,90,13,55,96,153,206,118,33,216,143,158,201,48,103,223,136,113,38,28,75,178,229,93,10,243,164,135,208,41,126,198,145,104,63,5,82,171,252,68,19,234,189,0,88,176,232,125,37,205,149,250,162,74,18,135,223,55,111,233,177,89,1,148,204,36,124,19,75,163,251,110,54,222,134,207,151,127,39,178,234,2,90,53,109,133,221,72,16,248,160,38,126,150,206,91,3,235,179,220,132,108,52,161,249,17,73,131,219,51,107,254,166,78,22,121,33,201,145,4,92,180,236,106,50,218,130,23,79,167,255,144,200,32,120,237,181,93,5,76,20,252,164,49,105,129,217,182,238,6,94,203,147,123,35,165,253,21,77,216,128,104,48,95,7,239,183,34,122,146,202,27,67,171,243,102,62,214,142,225,185,81,9,156,196,44,116,242,170,66,26,143,215,63,103,8,80,184,224,117,45,197,157,212,140,100,60,169,241,25,65,46,118,158,198,83,11,227,187,61,101,141,213,64,24,240,168,199,159,119,47,186,226,10,82,152,192,40,112,229,189,85,13,98,58,210,138,31,71,175,247,113,41,193,153,12,84,188,228,139,211,59,99,246,174,70,30,87,15,231,191,42,114,154,194,173,245,29,69,208,136,96,56,190,230,14,86,195,155,115,43,68,28,244,172,57,97,137,209,0,89,178,235,121,32,203,146,242,171,64,25,139,210,57,96,249,160,75,18,128,217,50,107,11,82,185,224,114,43,192,153,239,182,93,4,150,207,36,125,29,68,175,246,100,61,214,143,22,79,164,253,111,54,221,132,228,189,86,15,157,196,47,118,195,154,113,40,186,227,8,81,49,104,131,218,72,17,250,163,58,99,136,209,67,26,241,168,200,145,122,35,177,232,3,90,44,117,158,199,85,12,231,190,222,135,108,53,167,254,21,76,213,140,103,62,172,245,30,71,39,126,149,204,94,7,236,181,155,194,41,112,226,187,80,9,105,48,219,130,16,73,162,251,98,59,208,137,27,66,169,240,144,201,34,123,233,176,91,2,116,45,198,159,13,84,191,230,134,223,52,109,255,166,77,20,141,212,63,102,244,173,70,31,127,38,205,148,6,95,180,237,88,1,234,179,33,120,147,202,170,243,24,65,211,138,97,56,161,248,19,74,216,129,106,51,83,10,225,184,42,115,152,193,183,238,5,92,206,151,124,37,69,28,247,174,60,101,142,215,78,23,252,165,55,110,133,220,188,229,14,87,197,156,119,46,0,90,180,238,117,47,193,155,234,176,94,4,159,197,43,113,201,147,125,39,188,230,8,82,35,121,151,205,86,12,226,184,143,213,59,97,250,160,78,20,101,63,209,139,16,74,164,254,70,28,242,168,51,105,135,221,172,246,24,66,217,131,109,55,3,89,183,237,118,44,194,152,233,179,93,7,156,198,40,114,202,144,126,36,191,229,11,81,32,122,148,206,85,15,225,187,140,214,56,98,249,163,77,23,102,60,210,136,19,73,167,253,69,31,241,171,48,106,132,222,175,245,27,65,218,128,110,52,6,92,178,232,115,41,199,157,236,182,88,2,153,195,45,119,207,149,123,33,186,224,14,84,37,127,145,203,80,10,228,190,137,211,61,103,252,166,72,18,99,57,215,141,22,76,162,248,64,26,244,174,53,111,129,219,170,240,30,68,223,133,107,49,5,95,177,235,112,42,196,158,239,181,91,1,154,192,46,116,204,150,120,34,185,227,13,87,38,124,146,200,83,9,231,189,138,208,62,100,255,165,75,17,96,58,212,142,21,79,161,251,67,25,247,173,54,108,130,216,169,243,29,71,220,134,104,50,0,91,182,237,113,42,199,156,226,185,84,15,147,200,37,126,217,130,111,52,168,243,30,69,59,96,141,214,74,17,252,167,175,244,25,66,222,133,104,51,77,22,251,160,60,103,138,209,118,45,192,155,7,92,177,234,148,207,34,121,229,190,83,8,67,24,245,174,50,105,132,223,161,250,23,76,208,139,102,61,154,193,44,119,235,176,93,6,120,35,206,149,9,82,191,228,236,183,90,1,157,198,43,112,14,85,184,227,127,36,201,146,53,110,131,216,68,31,242,169,215,140,97,58,166,253,16,75,134,221,48,107,247,172,65,26,100,63,210,137,21,78,163,248,95,4,233,178,46,117,152,195,189,230,11,80,204,151,122,33,41,114,159,196,88,3,238,181,203,144,125,38,186,225,12,87,240,171,70,29,129,218,55,108,18,73,164,255,99,56,213,142,197,158,115,40,180,239,2,89,39,124,145,202,86,13,224,187,28,71,170,241,109,54,219,128,254,165,72,19,143,212,57,98,106,49,220,135,27,64,173,246,136,211,62,101,249,162,79,20,179,232,5,94,194,153,116,47,81,10,231,188,32,123,150,205,0,92,184,228,109,49,213,137,218,134,98,62,183,235,15,83,169,245,17,77,196,152,124,32,115,47,203,151,30,66,166,250,79,19,247,171,34,126,154,198,149,201,45,113,248,164,64,28,230,186,94,2,139,215,51,111,60,96,132,216,81,13,233,181,158,194,38,122,243,175,75,23,68,24,252,160,41,117,145,205,55,107,143,211,90,6,226,190,237,177,85,9,128,220,56,100,209,141,105,53,188,224,4,88,11,87,179,239,102,58,222,130,120,36,192,156,21,73,173,241,162,254,26,70,207,147,119,43,33,125,153,197,76,16,244,168,251,167,67,31,150,202,46,114,136,212,48,108,229,185,93,1,82,14,234,182,63,99,135,219,110,50,214,138,3,95,187,231,180,232,12,80,217,133,97,61,199,155,127,35,170,246,18,78,29,65,165,249,112,44,200,148,191,227,7,91,210,142,106,54,101,57,221,129,8,84,176,236,22,74,174,242,123,39,195,159,204,144,116,40,161,253,25,69,240,172,72,20,157,193,37,121,42,118,146,206,71,27,255,163,89,5,225,189,52,104,140,208,131,223,59,103,238,178,86,10,0,93,186,231,105,52,211,142,210,143,104,53,187,230,1,92,185,228,3,94,208,141,106,55,107,54,209,140,2,95,184,229,111,50,213,136,6,91,188,225,189,224,7,90,212,137,110,51,214,139,108,49,191,226,5,88,4,89,190,227,109,48,215,138,222,131,100,57,183,234,13,80,12,81,182,235,101,56,223,130,103,58,221,128,14,83,180,233,181,232,15,82,220,129,102,59,177,236,11,86,216,133,98,63,99,62,217,132,10,87,176,237,8,85,178,239,97,60,219,134,218,135,96,61,179,238,9,84,161,252,27,70,200,149,114,47,115,46,201,148,26,71,160,253,24,69,162,255,113,44,203,150,202,151,112,45,163,254,25,68,206,147,116,41,167,250,29,64,28,65,166,251,117,40,207,146,119,42,205,144,30,67,164,249,165,248,31,66,204,145,118,43,127,34,197,152,22,75,172,241,173,240,23,74,196,153,126,35,198,155,124,33,175,242,21,72,20,73,174,243,125,32,199,154,16,77,170,247,121,36,195,158,194,159,120,37,171,246,17,76,169,244,19,78,192,157,122,39,123,38,193,156,18,79,168,245,0,94,188,226,101,59,217,135,202,148,118,40,175,241,19,77,137,215,53,107,236,178,80,14,67,29,255,161,38,120,154,196,15,81,179,237,106,52,214,136,197,155,121,39,160,254,28,66,134,216,58,100,227,189,95,1,76,18,240,174,41,119,149,203,30,64,162,252,123,37,199,153,212,138,104,54,177,239,13,83,151,201,43,117,242,172,78,16,93,3,225,191,56,102,132,218,17,79,173,243,116,42,200,150,219,133,103,57,190,224,2,92,152,198,36,122,253,163,65,31,82,12,238,176,55,105,139,213,60,98,128,222,89,7,229,187,246,168,74,20,147,205,47,113,181,235,9,87,208,142,108,50,127,33,195,157,26,68,166,248,51,109,143,209,86,8,234,180,249,167,69,27,156,194,32,126,186,228,6,88,223,129,99,61,112,46,204,146,21,75,169,247,34,124,158,192,71,25,251,165,232,182,84,10,141,211,49,111,171,245,23,73,206,144,114,44,97,63,221,131,4,90,184,230,45,115,145,207,72,22,244,170,231,185,91,5,130,220,62,96,164,250,24,70,193,159,125,35,110,48,210,140,11,85,183,233,0,95,190,225,97,62,223,128,194,157,124,35,163,252,29,66,153,198,39,120,248,167,70,25,91,4,229,186,58,101,132,219,47,112,145,206,78,17,240,175,237,178,83,12,140,211,50,109,182,233,8,87,215,136,105,54,116,43,202,149,21,74,171,244,94,1,224,191,63,96,129,222,156,195,34,125,253,162,67,28,199,152,121,38,166,249,24,71,5,90,187,228,100,59,218,133,113,46,207,144,16,79,174,241,179,236,13,82,210,141,108,51,232,183,86,9,137,214,55,104,42,117,148,203,75,20,245,170,188,227,2,93,221,130,99,60,126,33,192,159,31,64,161,254,37,122,155,196,68,27,250,165,231,184,89,6,134,217,56,103,147,204,45,114,242,173,76,19,81,14,239,176,48,111,142,209,10,85,180,235,107,52,213,138,200,151,118,41,169,246,23,72,226,189,92,3,131,220,61,98,32,127,158,193,65,30,255,160,123,36,197,154,26,69,164,251,185,230,7,88,216,135,102,57,205,146,115,44,172,243,18,77,15,80,177,238,110,49,208,143,84,11,234,181,53,106,139,212,150,201,40,119,247,168,73,22,0,96,192,160,157,253,93,61,39,71,231,135,186,218,122,26,78,46,142,238,211,179,19,115,105,9,169,201,244,148,52,84,156,252,92,60,1,97,193,161,187,219,123,27,38,70,230,134,210,178,18,114,79,47,143,239,245,149,53,85,104,8,168,200,37,69,229,133,184,216,120,24,2,98,194,162,159,255,95,63,107,11,171,203,246,150,54,86,76,44,140,236,209,177,17,113,185,217,121,25,36,68,228,132,158,254,94,62,3,99,195,163,247,151,55,87,106,10,170,202,208,176,16,112,77,45,141,237,74,42,138,234,215,183,23,119,109,13,173,205,240,144,48,80,4,100,196,164,153,249,89,57,35,67,227,131,190,222,126,30,214,182,22,118,75,43,139,235,241,145,49,81,108,12,172,204,152,248,88,56,5,101,197,165,191,223,127,31,34,66,226,130,111,15,175,207,242,146,50,82,72,40,136,232,213,181,21,117,33,65,225,129,188,220,124,28,6,102,198,166,155,251,91,59,243,147,51,83,110,14,174,206,212,180,20,116,73,41,137,233,189,221,125,29,32,64,224,128,154,250,90,58,7,103,199,167,0,97,194,163,153,248,91,58,47,78,237,140,182,215,116,21,94,63,156,253,199,166,5,100,113,16,179,210,232,137,42,75,188,221,126,31,37,68,231,134,147,242,81,48,10,107,200,169,226,131,32,65,123,26,185,216,205,172,15,110,84,53,150,247,101,4,167,198,252,157,62,95,74,43,136,233,211,178,17,112,59,90,249,152,162,195,96,1,20,117,214,183,141,236,79,46,217,184,27,122,64,33,130,227,246,151,52,85,111,14,173,204,135,230,69,36,30,127,220,189,168,201,106,11,49,80,243,146,202,171,8,105,83,50,145,240,229,132,39,70,124,29,190,223,148,245,86,55,13,108,207,174,187,218,121,24,34,67,224,129,118,23,180,213,239,142,45,76,89,56,155,250,192,161,2,99,40,73,234,139,177,208,115,18,7,102,197,164,158,255,92,61,175,206,109,12,54,87,244,149,128,225,66,35,25,120,219,186,241,144,51,82,104,9,170,203,222,191,28,125,71,38,133,228,19,114,209,176,138,235,72,41,60,93,254,159,165,196,103,6,77,44,143,238,212,181,22,119,98,3,160,193,251,154,57,88,0,98,196,166,149,247,81,51,55,85,243,145,162,192,102,4,110,12,170,200,251,153,63,93,89,59,157,255,204,174,8,106,220,190,24,122,73,43,141,239,235,137,47,77,126,28,186,216,178,208,118,20,39,69,227,129,133,231,65,35,16,114,212,182,165,199,97,3,48,82,244,150,146,240,86,52,7,101,195,161,203,169,15,109,94,60,154,248,252,158,56,90,105,11,173,207,121,27,189,223,236,142,40,74,78,44,138,232,219,185,31,125,23,117,211,177,130,224,70,36,32,66,228,134,181,215,113,19,87,53,147,241,194,160,6,100,96,2,164,198,245,151,49,83,57,91,253,159,172,206,104,10,14,108,202,168,155,249,95,61,139,233,79,45,30,124,218,184,188,222,120,26,41,75,237,143,229,135,33,67,112,18,180,214,210,176,22,116,71,37,131,225,242,144,54,84,103,5,163,193,197,167,1,99,80,50,148,246,156,254,88,58,9,107,205,175,171,201,111,13,62,92,250,152,46,76,234,136,187,217,127,29,25,123,221,191,140,238,72,42,64,34,132,230,213,183,17,115,119,21,179,209,226,128,38,68,0,99,198,165,145,242,87,52,63,92,249,154,174,205,104,11,126,29,184,219,239,140,41,74,65,34,135,228,208,179,22,117,252,159,58,89,109,14,171,200,195,160,5,102,82,49,148,247,130,225,68,39,19,112,213,182,189,222,123,24,44,79,234,137,229,134,35,64,116,23,178,209,218,185,28,127,75,40,141,238,155,248,93,62,10,105,204,175,164,199,98,1,53,86,243,144,25,122,223,188,136,235,78,45,38,69,224,131,183,212,113,18,103,4,161,194,246,149,48,83,88,59,158,253,201,170,15,108,215,180,17,114,70,37,128,227,232,139,46,77,121,26,191,220,169,202,111,12,56,91,254,157,150,245,80,51,7,100,193,162,43,72,237,142,186,217,124,31,20,119,210,177,133,230,67,32,85,54,147,240,196,167,2,97,106,9,172,207,251,152,61,94,50,81,244,151,163,192,101,6,13,110,203,168,156,255,90,57,76,47,138,233,221,190,27,120,115,16,181,214,226,129,36,71,206,173,8,107,95,60,153,250,241,146,55,84,96,3,166,197,176,211,118,21,33,66,231,132,143,236,73,42,30,125,216,187,0,100,200,172,141,233,69,33,7,99,207,171,138,238,66,38,14,106,198,162,131,231,75,47,9,109,193,165,132,224,76,40,28,120,212,176,145,245,89,61,27,127,211,183,150,242,94,58,18,118,218,190,159,251,87,51,21,113,221,185,152,252,80,52,56,92,240,148,181,209,125,25,63,91,247,147,178,214,122,30,54,82,254,154,187,223,115,23,49,85,249,157,188,216,116,16,36,64,236,136,169,205,97,5,35,71,235,143,174,202,102,2,42,78,226,134,167,195,111,11,45,73,229,129,160,196,104,12,112,20,184,220,253,153,53,81,119,19,191,219,250,158,50,86,126,26,182,210,243,151,59,95,121,29,177,213,244,144,60,88,108,8,164,192,225,133,41,77,107,15,163,199,230,130,46,74,98,6,170,206,239,139,39,67,101,1,173,201,232,140,32,68,72,44,128,228,197,161,13,105,79,43,135,227,194,166,10,110,70,34,142,234,203,175,3,103,65,37,137,237,204,168,4,96,84,48,156,248,217,189,17,117,83,55,155,255,222,186,22,114,90,62,146,246,215,179,31,123,93,57,149,241,208,180,24,124,0,101,202,175,137,236,67,38,15,106,197,160,134,227,76,41,30,123,212,177,151,242,93,56,17,116,219,190,152,253,82,55,60,89,246,147,181,208,127,26,51,86,249,156,186,223,112,21,34,71,232,141,171,206,97,4,45,72,231,130,164,193,110,11,120,29,178,215,241,148,59,94,119,18,189,216,254,155,52,81,102,3,172,201,239,138,37,64,105,12,163,198,224,133,42,79,68,33,142,235,205,168,7,98,75,46,129,228,194,167,8,109,90,63,144,245,211,182,25,124,85,48,159,250,220,185,22,115,240,149,58,95,121,28,179,214,255,154,53,80,118,19,188,217,238,139,36,65,103,2,173,200,225,132,43,78,104,13,162,199,204,169,6,99,69,32,143,234,195,166,9,108,74,47,128,229,210,183,24,125,91,62,145,244,221,184,23,114,84,49,158,251,136,237,66,39,1,100,203,174,135,226,77,40,14,107,196,161,150,243,92,57,31,122,213,176,153,252,83,54,16,117,218,191,180,209,126,27,61,88,247,146,187,222,113,20,50,87,248,157,170,207,96,5,35,70,233,140,165,192,111,10,44,73,230,131,0,102,204,170,133,227,73,47,23,113,219,189,146,244,94,56,46,72,226,132,171,205,103,1,57,95,245,147,188,218,112,22,92,58,144,246,217,191,21,115,75,45,135,225,206,168,2,100,114,20,190,216,247,145,59,93,101,3,169,207,224,134,44,74,184,222,116,18,61,91,241,151,175,201,99,5,42,76,230,128,150,240,90,60,19,117,223,185,129,231,77,43,4,98,200,174,228,130,40,78,97,7,173,203,243,149,63,89,118,16,186,220,202,172,6,96,79,41,131,229,221,187,17,119,88,62,148,242,109,11,161,199,232,142,36,66,122,28,182,208,255,153,51,85,67,37,143,233,198,160,10,108,84,50,152,254,209,183,29,123,49,87,253,155,180,210,120,30,38,64,234,140,163,197,111,9,31,121,211,181,154,252,86,48,8,110,196,162,141,235,65,39,213,179,25,127,80,54,156,250,194,164,14,104,71,33,139,237,251,157,55,81,126,24,178,212,236,138,32,70,105,15,165,195,137,239,69,35,12,106,192,166,158,248,82,52,27,125,215,177,167,193,107,13,34,68,238,136,176,214,124,26,53,83,249,159,0,103,206,169,129,230,79,40,31,120,209,182,158,249,80,55,62,89,240,151,191,216,113,22,33,70,239,136,160,199,110,9,124,27,178,213,253,154,51,84,99,4,173,202,226,133,44,75,66,37,140,235,195,164,13,106,93,58,147,244,220,187,18,117,248,159,54,81,121,30,183,208,231,128,41,78,102,1,168,207,198,161,8,111,71,32,137,238,217,190,23,112,88,63,150,241,132,227,74,45,5,98,203,172,155,252,85,50,26,125,212,179,186,221,116,19,59,92,245,146,165,194,107,12,36,67,234,141,237,138,35,68,108,11,162,197,242,149,60,91,115,20,189,218,211,180,29,122,82,53,156,251,204,171,2,101,77,42,131,228,145,246,95,56,16,119,222,185,142,233,64,39,15,104,193,166,175,200,97,6,46,73,224,135,176,215,126,25,49,86,255,152,21,114,219,188,148,243,90,61,10,109,196,163,139,236,69,34,43,76,229,130,170,205,100,3,52,83,250,157,181,210,123,28,105,14,167,192,232,143,38,65,118,17,184,223,247,144,57,94,87,48,153,254,214,177,24,127,72,47,134,225,201,174,7,96,0,104,208,184,189,213,109,5,103,15,183,223,218,178,10,98,206,166,30,118,115,27,163,203,169,193,121,17,20,124,196,172,129,233,81,57,60,84,236,132,230,142,54,94,91,51,139,227,79,39,159,247,242,154,34,74,40,64,248,144,149,253,69,45,31,119,207,167,162,202,114,26,120,16,168,192,197,173,21,125,209,185,1,105,108,4,188,212,182,222,102,14,11,99,219,179,158,246,78,38,35,75,243,155,249,145,41,65,68,44,148,252,80,56,128,232,237,133,61,85,55,95,231,143,138,226,90,50,62,86,238,134,131,235,83,59,89,49,137,225,228,140,52,92,240,152,32,72,77,37,157,245,151,255,71,47,42,66,250,146,191,215,111,7,2,106,210,186,216,176,8,96,101,13,181,221,113,25,161,201,204,164,28,116,22,126,198,174,171,195,123,19,33,73,241,153,156,244,76,36,70,46,150,254,251,147,43,67,239,135,63,87,82,58,130,234,136,224,88,48,53,93,229,141,160,200,112,24,29,117,205,165,199,175,23,127,122,18,170,194,110,6,190,214,211,187,3,107,9,97,217,177,180,220,100,12,0,105,210,187,185,208,107,2,111,6,189,212,214,191,4,109,222,183,12,101,103,14,181,220,177,216,99,10,8,97,218,179,161,200,115,26,24,113,202,163,206,167,28,117,119,30,165,204,127,22,173,196,198,175,20,125,16,121,194,171,169,192,123,18,95,54,141,228,230,143,52,93,48,89,226,139,137,224,91,50,129,232,83,58,56,81,234,131,238,135,60,85,87,62,133,236,254,151,44,69,71,46,149,252,145,248,67,42,40,65,250,147,32,73,242,155,153,240,75,34,79,38,157,244,246,159,36,77,190,215,108,5,7,110,213,188,209,184,3,106,104,1,186,211,96,9,178,219,217,176,11,98,15,102,221,180,182,223,100,13,31,118,205,164,166,207,116,29,112,25,162,203,201,160,27,114,193,168,19,122,120,17,170,195,174,199,124,21,23,126,197,172,225,136,51,90,88,49,138,227,142,231,92,53,55,94,229,140,63,86,237,132,134,239,84,61,80,57,130,235,233,128,59,82,64,41,146,251,249,144,43,66,47,70,253,148,150,255,68,45,158,247,76,37,39,78,245,156,241,152,35,74,72,33,154,243,0,106,212,190,181,223,97,11,119,29,163,201,194,168,22,124,238,132,58,80,91,49,143,229,153,243,77,39,44,70,248,146,193,171,21,127,116,30,160,202,182,220,98,8,3,105,215,189,47,69,251,145,154,240,78,36,88,50,140,230,237,135,57,83,159,245,75,33,42,64,254,148,232,130,60,86,93,55,137,227,113,27,165,207,196,174,16,122,6,108,210,184,179,217,103,13,94,52,138,224,235,129,63,85,41,67,253,151,156,246,72,34,176,218,100,14,5,111,209,187,199,173,19,121,114,24,166,204,35,73,247,157,150,252,66,40,84,62,128,234,225,139,53,95,205,167,25,115,120,18,172,198,186,208,110,4,15,101,219,177,226,136,54,92,87,61,131,233,149,255,65,43,32,74,244,158,12,102,216,178,185,211,109,7,123,17,175,197,206,164,26,112,188,214,104,2,9,99,221,183,203,161,31,117,126,20,170,192,82,56,134,236,231,141,51,89,37,79,241,155,144,250,68,46,125,23,169,195,200,162,28,118,10,96,222,180,191,213,107,1,147,249,71,45,38,76,242,152,228,142,48,90,81,59,133,239,0,107,214,189,177,218,103,12,127,20,169,194,206,165,24,115,254,149,40,67,79,36,153,242,129,234,87,60,48,91,230,141,225,138,55,92,80,59,134,237,158,245,72,35,47,68,249,146,31,116,201,162,174,197,120,19,96,11,182,221,209,186,7,108,223,180,9,98,110,5,184,211,160,203,118,29,17,122,199,172,33,74,247,156,144,251,70,45,94,53,136,227,239,132,57,82,62,85,232,131,143,228,89,50,65,42,151,252,240,155,38,77,192,171,22,125,113,26,167,204,191,212,105,2,14,101,216,179,163,200,117,30,18,121,196,175,220,183,10,97,109,6,187,208,93,54,139,224,236,135,58,81,34,73,244,159,147,248,69,46,66,41,148,255,243,152,37,78,61,86,235,128,140,231,90,49,188,215,106,1,13,102,219,176,195,168,21,126,114,25,164,207,124,23,170,193,205,166,27,112,3,104,213,190,178,217,100,15,130,233,84,63,51,88,229,142,253,150,43,64,76,39,154,241,157,246,75,32,44,71,250,145,226,137,52,95,83,56,133,238,99,8,181,222,210,185,4,111,28,119,202,161,173,198,123,16,0,108,216,180,173,193,117,25,71,43,159,243,234,134,50,94,142,226,86,58,35,79,251,151,201,165,17,125,100,8,188,208,1,109,217,181,172,192,116,24,70,42,158,242,235,135,51,95,143,227,87,59,34,78,250,150,200,164,16,124,101,9,189,209,2,110,218,182,175,195,119,27,69,41,157,241,232,132,48,92,140,224,84,56,33,77,249,149,203,167,19,127,102,10,190,210,3,111,219,183,174,194,118,26,68,40,156,240,233,133,49,93,141,225,85,57,32,76,248,148,202,166,18,126,103,11,191,211,4,104,220,176,169,197,113,29,67,47,155,247,238,130,54,90,138,230,82,62,39,75,255,147,205,161,21,121,96,12,184,212,5,105,221,177,168,196,112,28,66,46,154,246,239,131,55,91,139,231,83,63,38,74,254,146,204,160,20,120,97,13,185,213,6,106,222,178,171,199,115,31,65,45,153,245,236,128,52,88,136,228,80,60,37,73,253,145,207,163,23,123,98,14,186,214,7,107,223,179,170,198,114,30,64,44,152,244,237,129,53,89,137,229,81,61,36,72,252,144,206,162,22,122,99,15,187,215,0,109,218,183,169,196,115,30,79,34,149,248,230,139,60,81,158,243,68,41,55,90,237,128,209,188,11,102,120,21,162,207,33,76,251,150,136,229,82,63,110,3,180,217,199,170,29,112,191,210,101,8,22,123,204,161,240,157,42,71,89,52,131,238,66,47,152,245,235,134,49,92,13,96,215,186,164,201,126,19,220,177,6,107,117,24,175,194,147,254,73,36,58,87,224,141,99,14,185,212,202,167,16,125,44,65,246,155,133,232,95,50,253,144,39,74,84,57,142,227,178,223,104,5,27,118,193,172,132,233,94,51,45,64,247,154,203,166,17,124,98,15,184,213,26,119,192,173,179,222,105,4,85,56,143,226,252,145,38,75,165,200,127,18,12,97,214,187,234,135,48,93,67,46,153,244,59,86,225,140,146,255,72,37,116,25,174,195,221,176,7,106,198,171,28,113,111,2,181,216,137,228,83,62,32,77,250,151,88,53,130,239,241,156,43,70,23,122,205,160,190,211,100,9,231,138,61,80,78,35,148,249,168,197,114,31,1,108,219,182,121,20,163,206,208,189,10,103,54,91,236,129,159,242,69,40,0,110,220,178,165,203,121,23,87,57,139,229,242,156,46,64,174,192,114,28,11,101,215,185,249,151,37,75,92,50,128,238,65,47,157,243,228,138,56,86,22,120,202,164,179,221,111,1,239,129,51,93,74,36,150,248,184,214,100,10,29,115,193,175,130,236,94,48,39,73,251,149,213,187,9,103,112,30,172,194,44,66,240,158,137,231,85,59,123,21,167,201,222,176,2,108,195,173,31,113,102,8,186,212,148,250,72,38,49,95,237,131,109,3,177,223,200,166,20,122,58,84,230,136,159,241,67,45,25,119,197,171,188,210,96,14,78,32,146,252,235,133,55,89,183,217,107,5,18,124,206,160,224,142,60,82,69,43,153,247,88,54,132,234,253,147,33,79,15,97,211,189,170,196,118,24,246,152,42,68,83,61,143,225,161,207,125,19,4,106,216,182,155,245,71,41,62,80,226,140,204,162,16,126,105,7,181,219,53,91,233,135,144,254,76,34,98,12,190,208,199,169,27,117,218,180,6,104,127,17,163,205,141,227,81,63,40,70,244,154,116,26,168,198,209,191,13,99,35,77,255,145,134,232,90,52,0,111,222,177,161,206,127,16,95,48,129,238,254,145,32,79,190,209,96,15,31,112,193,174,225,142,63,80,64,47,158,241,97,14,191,208,192,175,30,113,62,81,224,143,159,240,65,46,223,176,1,110,126,17,160,207,128,239,94,49,33,78,255,144,194,173,28,115,99,12,189,210,157,242,67,44,60,83,226,141,124,19,162,205,221,178,3,108,35,76,253,146,130,237,92,51,163,204,125,18,2,109,220,179,252,147,34,77,93,50,131,236,29,114,195,172,188,211,98,13,66,45,156,243,227,140,61,82,153,246,71,40,56,87,230,137,198,169,24,119,103,8,185,214,39,72,249,150,134,233,88,55,120,23,166,201,217,182,7,104,248,151,38,73,89,54,135,232,167,200,121,22,6,105,216,183,70,41,152,247,231,136,57,86,25,118,199,168,184,215,102,9,91,52,133,234,250,149,36,75,4,107,218,181,165,202,123,20,229,138,59,84,68,43,154,245,186,213,100,11,27,116,197,170,58,85,228,139,155,244,69,42,101,10,187,212,196,171,26,117,132,235,90,53,37,74,251,148,219,180,5,106,122,21,164,203,0,112,224,144,221,173,61,77,167,215,71,55,122,10,154,234,83,35,179,195,142,254,110,30,244,132,20,100,41,89,201,185,166,214,70,54,123,11,155,235,1,113,225,145,220,172,60,76,245,133,21,101,40,88,200,184,82,34,178,194,143,255,111,31,81,33,177,193,140,252,108,28,246,134,22,102,43,91,203,187,2,114,226,146,223,175,63,79,165,213,69,53,120,8,152,232,247,135,23,103,42,90,202,186,80,32,176,192,141,253,109,29,164,212,68,52,121,9,153,233,3,115,227,147,222,174,62,78,162,210,66,50,127,15,159,239,5,117,229,149,216,168,56,72,241,129,17,97,44,92,204,188,86,38,182,198,139,251,107,27,4,116,228,148,217,169,57,73,163,211,67,51,126,14,158,238,87,39,183,199,138,250,106,26,240,128,16,96,45,93,205,189,243,131,19,99,46,94,206,190,84,36,180,196,137,249,105,25,160,208,64,48,125,13,157,237,7,119,231,151,218,170,58,74,85,37,181,197,136,248,104,24,242,130,18,98,47,95,207,191,6,118,230,150,219,171,59,75,161,209,65,49,124,12,156,236,0,113,226,147,217,168,59,74,175,222,77,60,118,7,148,229,67,50,161,208,154,235,120,9,236,157,14,127,53,68,215,166,134,247,100,21,95,46,189,204,41,88,203,186,240,129,18,99,197,180,39,86,28,109,254,143,106,27,136,249,179,194,81,32,17,96,243,130,200,185,42,91,190,207,92,45,103,22,133,244,82,35,176,193,139,250,105,24,253,140,31,110,36,85,198,183,151,230,117,4,78,63,172,221,56,73,218,171,225,144,3,114,212,165,54,71,13,124,239,158,123,10,153,232,162,211,64,49,34,83,192,177,251,138,25,104,141,252,111,30,84,37,182,199,97,16,131,242,184,201,90,43,206,191,44,93,23,102,245,132,164,213,70,55,125,12,159,238,11,122,233,152,210,163,48,65,231,150,5,116,62,79,220,173,72,57,170,219,145,224,115,2,51,66,209,160,234,155,8,121,156,237,126,15,69,52,167,214,112,1,146,227,169,216,75,58,223,174,61,76,6,119,228,149,181,196,87,38,108,29,142,255,26,107,248,137,195,178,33,80,246,135,20,101,47,94,205,188,89,40,187,202,128,241,98,19,0,114,228,150,213,167,49,67,183,197,83,33,98,16,134,244,115,1,151,229,166,212,66,48,196,182,32,82,17,99,245,135,230,148,2,112,51,65,215,165,81,35,181,199,132,246,96,18,149,231,113,3,64,50,164,214,34,80,198,180,247,133,19,97,209,163,53,71,4,118,224,146,102,20,130,240,179,193,87,37,162,208,70,52,119,5,147,225,21,103,241,131,192,178,36,86,55,69,211,161,226,144,6,116,128,242,100,22,85,39,177,195,68,54,160,210,145,227,117,7,243,129,23,101,38,84,194,176,191,205,91,41,106,24,142,252,8,122,236,158,221,175,57,75,204,190,40,90,25,107,253,143,123,9,159,237,174,220,74,56,89,43,189,207,140,254,104,26,238,156,10,120,59,73,223,173,42,88,206,188,255,141,27,105,157,239,121,11,72,58,172,222,110,28,138,248,187,201,95,45,217,171,61,79,12,126,232,154,29,111,249,139,200,186,44,94,170,216,78,60,127,13,155,233,136,250,108,30,93,47,185,203,63,77,219,169,234,152,14,124,251,137,31,109,46,92,202,184,76,62,168,218,153,235,125,15,0,115,230,149,209,162,55,68,191,204,89,42,110,29,136,251,99,16,133,246,178,193,84,39,220,175,58,73,13,126,235,152,198,181,32,83,23,100,241,130,121,10,159,236,168,219,78,61,165,214,67,48,116,7,146,225,26,105,252,143,203,184,45,94,145,226,119,4,64,51,166,213,46,93,200,187,255,140,25,106,242,129,20,103,35,80,197,182,77,62,171,216,156,239,122,9,87,36,177,194,134,245,96,19,232,155,14,125,57,74,223,172,52,71,210,161,229,150,3,112,139,248,109,30,90,41,188,207,63,76,217,170,238,157,8,123,128,243,102,21,81,34,183,196,92,47,186,201,141,254,107,24,227,144,5,118,50,65,212,167,249,138,31,108,40,91,206,189,70,53,160,211,151,228,113,2,154,233,124,15,75,56,173,222,37,86,195,176,244,135,18,97,174,221,72,59,127,12,153,234,17,98,247,132,192,179,38,85,205,190,43,88,28,111,250,137,114,1,148,231,163,208,69,54,104,27,142,253,185,202,95,44,215,164,49,66,6,117,224,147,11,120,237,158,218,169,60,79,180,199,82,33,101,22,131,240,0,116,232,156,205,185,37,81,135,243,111,27,74,62,162,214,19,103,251,143,222,170,54,66,148,224,124,8,89,45,177,197,38,82,206,186,235,159,3,119,161,213,73,61,108,24,132,240,53,65,221,169,248,140,16,100,178,198,90,46,127,11,151,227,76,56,164,208,129,245,105,29,203,191,35,87,6,114,238,154,95,43,183,195,146,230,122,14,216,172,48,68,21,97,253,137,106,30,130,246,167,211,79,59,237,153,5,113,32,84,200,188,121,13,145,229,180,192,92,40,254,138,22,98,51,71,219,175,152,236,112,4,85,33,189,201,31,107,247,131,210,166,58,78,139,255,99,23,70,50,174,218,12,120,228,144,193,181,41,93,190,202,86,34,115,7,155,239,57,77,209,165,244,128,28,104,173,217,69,49,96,20,136,252,42,94,194,182,231,147,15,123,212,160,60,72,25,109,241,133,83,39,187,207,158,234,118,2,199,179,47,91,10,126,226,150,64,52,168,220,141,249,101,17,242,134,26,110,63,75,215,163,117,1,157,233,184,204,80,36,225,149,9,125,44,88,196,176,102,18,142,250,171,223,67,55,0,117,234,159,201,188,35,86,143,250,101,16,70,51,172,217,3,118,233,156,202,191,32,85,140,249,102,19,69,48,175,218,6,115,236,153,207,186,37,80,137,252,99,22,64,53,170,223,5,112,239,154,204,185,38,83,138,255,96,21,67,54,169,220,12,121,230,147,197,176,47,90,131,246,105,28,74,63,160,213,15,122,229,144,198,179,44,89,128,245,106,31,73,60,163,214,10,127,224,149,195,182,41,92,133,240,111,26,76,57,166,211,9,124,227,150,192,181,42,95,134,243,108,25,79,58,165,208,24,109,242,135,209,164,59,78,151,226,125,8,94,43,180,193,27,110,241,132,210,167,56,77,148,225,126,11,93,40,183,194,30,107,244,129,215,162,61,72,145,228,123,14,88,45,178,199,29,104,247,130,212,161,62,75,146,231,120,13,91,46,177,196,20,97,254,139,221,168,55,66,155,238,113,4,82,39,184,205,23,98,253,136,222,171,52,65,152,237,114,7,81,36,187,206,18,103,248,141,219,174,49,68,157,232,119,2,84,33,190,203,17,100,251,142,216,173,50,71,158,235,116,1,87,34,189,200,0,118,236,154,197,179,41,95,151,225,123,13,82,36,190,200,51,69,223,169,246,128,26,108,164,210,72,62,97,23,141,251,102,16,138,252,163,213,79,57,241,135,29,107,52,66,216,174,85,35,185,207,144,230,124,10,194,180,46,88,7,113,235,157,204,186,32,86,9,127,229,147,91,45,183,193,158,232,114,4,255,137,19,101,58,76,214,160,104,30,132,242,173,219,65,55,170,220,70,48,111,25,131,245,61,75,209,167,248,142,20,98,153,239,117,3,92,42,176,198,14,120,226,148,203,189,39,81,133,243,105,31,64,54,172,218,18,100,254,136,215,161,59,77,182,192,90,44,115,5,159,233,33,87,205,187,228,146,8,126,227,149,15,121,38,80,202,188,116,2,152,238,177,199,93,43,208,166,60,74,21,99,249,143,71,49,171,221,130,244,110,24,73,63,165,211,140,250,96,22,222,168,50,68,27,109,247,129,122,12,150,224,191,201,83,37,237,155,1,119,40,94,196,178,47,89,195,181,234,156,6,112,184,206,84,34,125,11,145,231,28,106,240,134,217,175,53,67,139,253,103,17,78,56,162,212,0,119,238,153,193,182,47,88,159,232,113,6,94,41,176,199,35,84,205,186,226,149,12,123,188,203,82,37,125,10,147,228,70,49,168,223,135,240,105,30,217,174,55,64,24,111,246,129,101,18,139,252,164,211,74,61,250,141,20,99,59,76,213,162,140,251,98,21,77,58,163,212,19,100,253,138,210,165,60,75,175,216,65,54,110,25,128,247,48,71,222,169,241,134,31,104,202,189,36,83,11,124,229,146,85,34,187,204,148,227,122,13,233,158,7,112,40,95,198,177,118,1,152,239,183,192,89,46,5,114,235,156,196,179,42,93,154,237,116,3,91,44,181,194,38,81,200,191,231,144,9,126,185,206,87,32,120,15,150,225,67,52,173,218,130,245,108,27,220,171,50,69,29,106,243,132,96,23,142,249,161,214,79,56,255,136,17,102,62,73,208,167,137,254,103,16,72,63,166,209,22,97,248,143,215,160,57,78,170,221,68,51,107,28,133,242,53,66,219,172,244,131,26,109,207,184,33,86,14,121,224,151,80,39,190,201,145,230,127,8,236,155,2,117,45,90,195,180,115,4,157,234,178,197,92,43,0,120,240,136,253,133,13,117,231,159,23,111,26,98,234,146,211,171,35,91,46,86,222,166,52,76,196,188,201,177,57,65,187,195,75,51,70,62,182,206,92,36,172,212,161,217,81,41,104,16,152,224,149,237,101,29,143,247,127,7,114,10,130,250,107,19,155,227,150,238,102,30,140,244,124,4,113,9,129,249,184,192,72,48,69,61,181,205,95,39,175,215,162,218,82,42,208,168,32,88,45,85,221,165,55,79,199,191,202,178,58,66,3,123,243,139,254,134,14,118,228,156,20,108,25,97,233,145,214,174,38,94,43,83,219,163,49,73,193,185,204,180,60,68,5,125,245,141,248,128,8,112,226,154,18,106,31,103,239,151,109,21,157,229,144,232,96,24,138,242,122,2,119,15,135,255,190,198,78,54,67,59,179,203,89,33,169,209,164,220,84,44,189,197,77,53,64,56,176,200,90,34,170,210,167,223,87,47,110,22,158,230,147,235,99,27,137,241,121,1,116,12,132,252,6,126,246,142,251,131,11,115,225,153,17,105,28,100,236,148,213,173,37,93,40,80,216,160,50,74,194,186,207,183,63,71,0,121,242,139,249,128,11,114,239,150,29,100,22,111,228,157,195,186,49,72,58,67,200,177,44,85,222,167,213,172,39,94,155,226,105,16,98,27,144,233,116,13,134,255,141,244,127,6,88,33,170,211,161,216,83,42,183,206,69,60,78,55,188,197,43,82,217,160,210,171,32,89,196,189,54,79,61,68,207,182,232,145,26,99,17,104,227,154,7,126,245,140,254,135,12,117,176,201,66,59,73,48,187,194,95,38,173,212,166,223,84,45,115,10,129,248,138,243,120,1,156,229,110,23,101,28,151,238,86,47,164,221,175,214,93,36,185,192,75,50,64,57,178,203,149,236,103,30,108,21,158,231,122,3,136,241,131,250,113,8,205,180,63,70,52,77,198,191,34,91,208,169,219,162,41,80,14,119,252,133,247,142,5,124,225,152,19,106,24,97,234,147,125,4,143,246,132,253,118,15,146,235,96,25,107,18,153,224,190,199,76,53,71,62,181,204,81,40,163,218,168,209,90,35,230,159,20,109,31,102,237,148,9,112,251,130,240,137,2,123,37,92,215,174,220,165,46,87,202,179,56,65,51,74,193,184,0,122,244,142,245,143,1,123,247,141,3,121,2,120,246,140,243,137,7,125,6,124,242,136,4,126,240,138,241,139,5,127,251,129,15,117,14,116,250,128,12,118,248,130,249,131,13,119,8,114,252,134,253,135,9,115,255,133,11,113,10,112,254,132,235,145,31,101,30,100,234,144,28,102,232,146,233,147,29,103,24,98,236,150,237,151,25,99,239,149,27,97,26,96,238,148,16,106,228,158,229,159,17,107,231,157,19,105,18,104,230,156,227,153,23,109,22,108,226,152,20,110,224,154,225,155,21,111,203,177,63,69,62,68,202,176,60,70,200,178,201,179,61,71,56,66,204,182,205,183,57,67,207,181,59,65,58,64,206,180,48,74,196,190,197,191,49,75,199,189,51,73,50,72,198,188,195,185,55,77,54,76,194,184,52,78,192,186,193,187,53,79,32,90,212,174,213,175,33,91,215,173,35,89,34,88,214,172,211,169,39,93,38,92,210,168,36,94,208,170,209,171,37,95,219,161,47,85,46,84,218,160,44,86,216,162,217,163,45,87,40,82,220,166,221,167,41,83,223,165,43,81,42,80,222,164,0,123,246,141,241,138,7,124,255,132,9,114,14,117,248,131,227,152,21,110,18,105,228,159,28,103,234,145,237,150,27,96,219,160,45,86,42,81,220,167,36,95,210,169,213,174,35,88,56,67,206,181,201,178,63,68,199,188,49,74,54,77,192,187,171,208,93,38,90,33,172,215,84,47,162,217,165,222,83,40,72,51,190,197,185,194,79,52,183,204,65,58,70,61,176,203,112,11,134,253,129,250,119,12,143,244,121,2,126,5,136,243,147,232,101,30,98,25,148,239,108,23,154,225,157,230,107,16,75,48,189,198,186,193,76,55,180,207,66,57,69,62,179,200,168,211,94,37,89,34,175,212,87,44,161,218,166,221,80,43,144,235,102,29,97,26,151,236,111,20,153,226,158,229,104,19,115,8,133,254,130,249,116,15,140,247,122,1,125,6,139,240,224,155,22,109,17,106,231,156,31,100,233,146,238,149,24,99,3,120,245,142,242,137,4,127,252,135,10,113,13,118,251,128,59,64,205,182,202,177,60,71,196,191,50,73,53,78,195,184,216,163,46,85,41,82,223,164,39,92,209,170,214,173,32,91,0,124,248,132,237,145,21,105,199,187,63,67,42,86,210,174,147,239,107,23,126,2,134,250,84,40,172,208,185,197,65,61,59,71,195,191,214,170,46,82,252,128,4,120,17,109,233,149,168,212,80,44,69,57,189,193,111,19,151,235,130,254,122,6,118,10,142,242,155,231,99,31,177,205,73,53,92,32,164,216,229,153,29,97,8,116,240,140,34,94,218,166,207,179,55,75,77,49,181,201,160,220,88,36,138,246,114,14,103,27,159,227,222,162,38,90,51,79,203,183,25,101,225,157,244,136,12,112,236,144,20,104,1,125,249,133,43,87,211,175,198,186,62,66,127,3,135,251,146,238,106,22,184,196,64,60,85,41,173,209,215,171,47,83,58,70,194,190,16,108,232,148,253,129,5,121,68,56,188,192,169,213,81,45,131,255,123,7,110,18,150,234,154,230,98,30,119,11,143,243,93,33,165,217,176,204,72,52,9,117,241,141,228,152,28,96,206,178,54,74,35,95,219,167,161,221,89,37,76,48,180,200,102,26,158,226,139,247,115,15,50,78,202,182,223,163,39,91,245,137,13,113,24,100,224,156,0,125,250,135,233,148,19,110,207,178,53,72,38,91,220,161,131,254,121,4,106,23,144,237,76,49,182,203,165,216,95,34,27,102,225,156,242,143,8,117,212,169,46,83,61,64,199,186,152,229,98,31,113,12,139,246,87,42,173,208,190,195,68,57,54,75,204,177,223,162,37,88,249,132,3,126,16,109,234,151,181,200,79,50,92,33,166,219,122,7,128,253,147,238,105,20,45,80,215,170,196,185,62,67,226,159,24,101,11,118,241,140,174,211,84,41,71,58,189,192,97,28,155,230,136,245,114,15,108,17,150,235,133,248,127,2,163,222,89,36,74,55,176,205,239,146,21,104,6,123,252,129,32,93,218,167,201,180,51,78,119,10,141,240,158,227,100,25,184,197,66,63,81,44,171,214,244,137,14,115,29,96,231,154,59,70,193,188,210,175,40,85,90,39,160,221,179,206,73,52,149,232,111,18,124,1,134,251,217,164,35,94,48,77,202,183,22,107,236,145,255,130,5,120,65,60,187,198,168,213,82,47,142,243,116,9,103,26,157,224,194,191,56,69,43,86,209,172,13,112,247,138,228,153,30,99,0,126,252,130,229,155,25,103,215,169,43,85,50,76,206,176,179,205,79,49,86,40,170,212,100,26,152,230,129,255,125,3,123,5,135,249,158,224,98,28,172,210,80,46,73,55,181,203,200,182,52,74,45,83,209,175,31,97,227,157,250,132,6,120,246,136,10,116,19,109,239,145,33,95,221,163,196,186,56,70,69,59,185,199,160,222,92,34,146,236,110,16,119,9,139,245,141,243,113,15,104,22,148,234,90,36,166,216,191,193,67,61,62,64,194,188,219,165,39,89,233,151,21,107,12,114,240,142,241,143,13,115,20,106,232,150,38,88,218,164,195,189,63,65,66,60,190,192,167,217,91,37,149,235,105,23,112,14,140,242,138,244,118,8,111,17,147,237,93,35,161,223,184,198,68,58,57,71,197,187,220,162,32,94,238,144,18,108,11,117,247,137,7,121,251,133,226,156,30,96,208,174,44,82,53,75,201,183,180,202,72,54,81,47,173,211,99,29,159,225,134,248,122,4,124,2,128,254,153,231,101,27,171,213,87,41,78,48,178,204,207,177,51,77,42,84,214,168,24,102,228,154,253,131,1,127,0,127,254,129,225,158,31,96,223,160,33,94,62,65,192,191,163,220,93,34,66,61,188,195,124,3,130,253,157,226,99,28,91,36,165,218,186,197,68,59,132,251,122,5,101,26,155,228,248,135,6,121,25,102,231,152,39,88,217,166,198,185,56,71,182,201,72,55,87,40,169,214,105,22,151,232,136,247,118,9,21,106,235,148,244,139,10,117,202,181,52,75,43,84,213,170,237,146,19,108,12,115,242,141,50,77,204,179,211,172,45,82,78,49,176,207,175,208,81,46,145,238,111,16,112,15,142,241,113,14,143,240,144,239,110,17,174,209,80,47,79,48,177,206,210,173,44,83,51,76,205,178,13,114,243,140,236,147,18,109,42,85,212,171,203,180,53,74,245,138,11,116,20,107,234,149,137,246,119,8,104,23,150,233,86,41,168,215,183,200,73,54,199,184,57,70,38,89,216,167,24,103,230,153,249,134,7,120,100,27,154,229,133,250,123,4,187,196,69,58,90,37,164,219,156,227,98,29,125,2,131,252,67,60,189,194,162,221,92,35,63,64,193,190,222,161,32,95,224,159,30,97,1,126,255,128,0,128,29,157,58,186,39,167,116,244,105,233,78,206,83,211,232,104,245,117,210,82,207,79,156,28,129,1,166,38,187,59,205,77,208,80,247,119,234,106,185,57,164,36,131,3,158,30,37,165,56,184,31,159,2,130,81,209,76,204,107,235,118,246,135,7,154,26,189,61,160,32,243,115,238,110,201,73,212,84,111,239,114,242,85,213,72,200,27,155,6,134,33,161,60,188,74,202,87,215,112,240,109,237,62,190,35,163,4,132,25,153,162,34,191,63,152,24,133,5,214,86,203,75,236,108,241,113,19,147,14,142,41,169,52,180,103,231,122,250,93,221,64,192,251,123,230,102,193,65,220,92,143,15,146,18,181,53,168,40,222,94,195,67,228,100,249,121,170,42,183,55,144,16,141,13,54,182,43,171,12,140,17,145,66,194,95,223,120,248,101,229,148,20,137,9,174,46,179,51,224,96,253,125,218,90,199,71,124,252,97,225,70,198,91,219,8,136,21,149,50,178,47,175,89,217,68,196,99,227,126,254,45,173,48,176,23,151,10,138,177,49,172,44,139,11,150,22,197,69,216,88,255,127,226,98,0,129,31,158,62,191,33,160,124,253,99,226,66,195,93,220,248,121,231,102,198,71,217,88,132,5,155,26,186,59,165,36,237,108,242,115,211,82,204,77,145,16,142,15,175,46,176,49,21,148,10,139,43,170,52,181,105,232,118,247,87,214,72,201,199,70,216,89,249,120,230,103,187,58,164,37,133,4,154,27,63,190,32,161,1,128,30,159,67,194,92,221,125,252,98,227,42,171,53,180,20,149,11,138,86,215,73,200,104,233,119,246,210,83,205,76,236,109,243,114,174,47,177,48,144,17,143,14,147,18,140,13,173,44,178,51,239,110,240,113,209,80,206,79,107,234,116,245,85,212,74,203,23,150,8,137,41,168,54,183,126,255,97,224,64,193,95,222,2,131,29,156,60,189,35,162,134,7,153,24,184,57,167,38,250,123,229,100,196,69,219,90,84,213,75,202,106,235,117,244,40,169,55,182,22,151,9,136,172,45,179,50,146,19,141,12,208,81,207,78,238,111,241,112,185,56,166,39,135,6,152,25,197,68,218,91,251,122,228,101,65,192,94,223,127,254,96,225,61,188,34,163,3,130,28,157,0,130,25,155,50,176,43,169,100,230,125,255,86,212,79,205,200,74,209,83,250,120,227,97,172,46,181,55,158,28,135,5,141,15,148,22,191,61,166,36,233,107,240,114,219,89,194,64,69,199,92,222,119,245,110,236,33,163,56,186,19,145,10,136,7,133,30,156,53,183,44,174,99,225,122,248,81,211,72,202,207,77,214,84,253,127,228,102,171,41,178,48,153,27,128,2,138,8,147,17,184,58,161,35,238,108,247,117,220,94,197,71,66,192,91,217,112,242,105,235,38,164,63,189,20,150,13,143,14,140,23,149,60,190,37,167,106,232,115,241,88,218,65,195,198,68,223,93,244,118,237,111,162,32,187,57,144,18,137,11,131,1,154,24,177,51,168,42,231,101,254,124,213,87,204,78,75,201,82,208,121,251,96,226,47,173,54,180,29,159,4,134,9,139,16,146,59,185,34,160,109,239,116,246,95,221,70,196,193,67,216,90,243,113,234,104,165,39,188,62,151,21,142,12,132,6,157,31,182,52,175,45,224,98,249,123,210,80,203,73,76,206,85,215,126,252,103,229,40,170,49,179,26,152,3,129,0,131,27,152,54,181,45,174,108,239,119,244,90,217,65,194,216,91,195,64,238,109,245,118,180,55,175,44,130,1,153,26,173,46,182,53,155,24,128,3,193,66,218,89,247,116,236,111,117,246,110,237,67,192,88,219,25,154,2,129,47,172,52,183,71,196,92,223,113,242,106,233,43,168,48,179,29,158,6,133,159,28,132,7,169,42,178,49,243,112,232,107,197,70,222,93,234,105,241,114,220,95,199,68,134,5,157,30,176,51,171,40,50,177,41,170,4,135,31,156,94,221,69,198,104,235,115,240,142,13,149,22,184,59,163,32,226,97,249,122,212,87,207,76,86,213,77,206,96,227,123,248,58,185,33,162,12,143,23,148,35,160,56,187,21,150,14,141,79,204,84,215,121,250,98,225,251,120,224,99,205,78,214,85,151,20,140,15,161,34,186,57,201,74,210,81,255,124,228,103,165,38,190,61,147,16,136,11,17,146,10,137,39,164,60,191,125,254,102,229,75,200,80,211,100,231,127,252,82,209,73,202,8,139,19,144,62,189,37,166,188,63,167,36,138,9,145,18,208,83,203,72,230,101,253,126,0,132,21,145,42,174,63,187,84,208,65,197,126,250,107,239,168,44,189,57,130,6,151,19,252,120,233,109,214,82,195,71,77,201,88,220,103,227,114,246,25,157,12,136,51,183,38,162,229,97,240,116,207,75,218,94,177,53,164,32,155,31,142,10,154,30,143,11,176,52,165,33,206,74,219,95,228,96,241,117,50,182,39,163,24,156,13,137,102,226,115,247,76,200,89,221,215,83,194,70,253,121,232,108,131,7,150,18,169,45,188,56,127,251,106,238,85,209,64,196,43,175,62,186,1,133,20,144,41,173,60,184,3,135,22,146,125,249,104,236,87,211,66,198,129,5,148,16,171,47,190,58,213,81,192,68,255,123,234,110,100,224,113,245,78,202,91,223,48,180,37,161,26,158,15,139,204,72,217,93,230,98,243,119,152,28,141,9,178,54,167,35,179,55,166,34,153,29,140,8,231,99,242,118,205,73,216,92,27,159,14,138,49,181,36,160,79,203,90,222,101,225,112,244,254,122,235,111,212,80,193,69,170,46,191,59,128,4,149,17,86,210,67,199,124,248,105,237,2,134,23,147,40,172,61,185,0,133,23,146,46,171,57,188,92,217,75,206,114,247,101,224,184,61,175,42,150,19,129,4,228,97,243,118,202,79,221,88,109,232,122,255,67,198,84,209,49,180,38,163,31,154,8,141,213,80,194,71,251,126,236,105,137,12,158,27,167,34,176,53,218,95,205,72,244,113,227,102,134,3,145,20,168,45,191,58,98,231,117,240,76,201,91,222,62,187,41,172,16,149,7,130,183,50,160,37,153,28,142,11,235,110,252,121,197,64,210,87,15,138,24,157,33,164,54,179,83,214,68,193,125,248,106,239,169,44,190,59,135,2,144,21,245,112,226,103,219,94,204,73,17,148,6,131,63,186,40,173,77,200,90,223,99,230,116,241,196,65,211,86,234,111,253,120,152,29,143,10,182,51,161,36,124,249,107,238,82,215,69,192,32,165,55,178,14,139,25,156,115,246,100,225,93,216,74,207,47,170,56,189,1,132,22,147,203,78,220,89,229,96,242,119,151,18,128,5,185,60,174,43,30,155,9,140,48,181,39,162,66,199,85,208,108,233,123,254,166,35,177,52,136,13,159,26,250,127,237,104,212,81,195,70,0,134,17,151,34,164,51,181,68,194,85,211,102,224,119,241,136,14,153,31,170,44,187,61,204,74,221,91,238,104,255,121,13,139,28,154,47,169,62,184,73,207,88,222,107,237,122,252,133,3,148,18,167,33,182,48,193,71,208,86,227,101,242,116,26,156,11,141,56,190,41,175,94,216,79,201,124,250,109,235,146,20,131,5,176,54,161,39,214,80,199,65,244,114,229,99,23,145,6,128,53,179,36,162,83,213,66,196,113,247,96,230,159,25,142,8,189,59,172,42,219,93,202,76,249,127,232,110,52,178,37,163,22,144,7,129,112,246,97,231,82,212,67,197,188,58,173,43,158,24,143,9,248,126,233,111,218,92,203,77,57,191,40,174,27,157,10,140,125,251,108,234,95,217,78,200,177,55,160,38,147,21,130,4,245,115,228,98,215,81,198,64,46,168,63,185,12,138,29,155,106,236,123,253,72,206,89,223,166,32,183,49,132,2,149,19,226,100,243,117,192,70,209,87,35,165,50,180,1,135,16,150,103,225,118,240,69,195,84,210,171,45,186,60,137,15,152,30,239,105,254,120,205,75,220,90,0,135,19,148,38,161,53,178,76,203,95,216,106,237,121,254,152,31,139,12,190,57,173,42,212,83,199,64,242,117,225,102,45,170,62,185,11,140,24,159,97,230,114,245,71,192,84,211,181,50,166,33,147,20,128,7,249,126,234,109,223,88,204,75,90,221,73,206,124,251,111,232,22,145,5,130,48,183,35,164,194,69,209,86,228,99,247,112,142,9,157,26,168,47,187,60,119,240,100,227,81,214,66,197,59,188,40,175,29,154,14,137,239,104,252,123,201,78,218,93,163,36,176,55,133,2,150,17,180,51,167,32,146,21,129,6,248,127,235,108,222,89,205,74,44,171,63,184,10,141,25,158,96,231,115,244,70,193,85,210,153,30,138,13,191,56,172,43,213,82,198,65,243,116,224,103,1,134,18,149,39,160,52,179,77,202,94,217,107,236,120,255,238,105,253,122,200,79,219,92,162,37,177,54,132,3,151,16,118,241,101,226,80,215,67,196,58,189,41,174,28,155,15,136,195,68,208,87,229,98,246,113,143,8,156,27,169,46,186,61,91,220,72,207,125,250,110,233,23,144,4,131,49,182,34,165,0,136,13,133,26,146,23,159,52,188,57,177,46,166,35,171,104,224,101,237,114,250,127,247,92,212,81,217,70,206,75,195,208,88,221,85,202,66,199,79,228,108,233,97,254,118,243,123,184,48,181,61,162,42,175,39,140,4,129,9,150,30,155,19,189,53,176,56,167,47,170,34,137,1,132,12,147,27,158,22,213,93,216,80,207,71,194,74,225,105,236,100,251,115,246,126,109,229,96,232,119,255,122,242,89,209,84,220,67,203,78,198,5,141,8,128,31,151,18,154,49,185,60,180,43,163,38,174,103,239,106,226,125,245,112,248,83,219,94,214,73,193,68,204,15,135,2,138,21,157,24,144,59,179,54,190,33,169,44,164,183,63,186,50,173,37,160,40,131,11,142,6,153,17,148,28,223,87,210,90,197,77,200,64,235,99,230,110,241,121,252,116,218,82,215,95,192,72,205,69,238,102,227,107,244,124,249,113,178,58,191,55,168,32,165,45,134,14,139,3,156,20,145,25,10,130,7,143,16,152,29,149,62,182,51,187,36,172,41,161,98,234,111,231,120,240,117,253,86,222,91,211,76,196,65,201,0,137,15,134,30,151,17,152,60,181,51,186,34,171,45,164,120,241,119,254,102,239,105,224,68,205,75,194,90,211,85,220,240,121,255,118,238,103,225,104,204,69,195,74,210,91,221,84,136,1,135,14,150,31,153,16,180,61,187,50,170,35,165,44,253,116,242,123,227,106,236,101,193,72,206,71,223,86,208,89,133,12,138,3,155,18,148,29,185,48,182,63,167,46,168,33,13,132,2,139,19,154,28,149,49,184,62,183,47,166,32,169,117,252,122,243,107,226,100,237,73,192,70,207,87,222,88,209,231,110,232,97,249,112,246,127,219,82,212,93,197,76,202,67,159,22,144,25,129,8,142,7,163,42,172,37,189,52,178,59,23,158,24,145,9,128,6,143,43,162,36,173,53,188,58,179,111,230,96,233,113,248,126,247,83,218,92,213,77,196,66,203,26,147,21,156,4,141,11,130,38,175,41,160,56,177,55,190,98,235,109,228,124,245,115,250,94,215,81,216,64,201,79,198,234,99,229,108,244,125,251,114,214,95,217,80,200,65,199,78,146,27,157,20,140,5,131,10,174,39,161,40,176,57,191,54,0,138,9,131,18,152,27,145,36,174,45,167,54,188,63,181,72,194,65,203,90,208,83,217,108,230,101,239,126,244,119,253,144,26,153,19,130,8,139,1,180,62,189,55,166,44,175,37,216,82,209,91,202,64,195,73,252,118,245,127,238,100,231,109,61,183,52,190,47,165,38,172,25,147,16,154,11,129,2,136,117,255,124,246,103,237,110,228,81,219,88,210,67,201,74,192,173,39,164,46,191,53,182,60,137,3,128,10,155,17,146,24,229,111,236,102,247,125,254,116,193,75,200,66,211,89,218,80,122,240,115,249,104,226,97,235,94,212,87,221,76,198,69,207,50,184,59,177,32,170,41,163,22,156,31,149,4,142,13,135,234,96,227,105,248,114,241,123,206,68,199,77,220,86,213,95,162,40,171,33,176,58,185,51,134,12,143,5,148,30,157,23,71,205,78,196,85,223,92,214,99,233,106,224,113,251,120,242,15,133,6,140,29,151,20,158,43,161,34,168,57,179,48,186,215,93,222,84,197,79,204,70,243,121,250,112,225,107,232,98,159,21,150,28,141,7,132,14,187,49,178,56,169,35,160,42,0,139,11,128,22,157,29,150,44,167,39,172,58,177,49,186,88,211,83,216,78,197,69,206,116,255,127,244,98,233,105,226,176,59,187,48,166,45,173,38,156,23,151,28,138,1,129,10,232,99,227,104,254,117,245,126,196,79,207,68,210,89,217,82,125,246,118,253,107,224,96,235,81,218,90,209,71,204,76,199,37,174,46,165,51,184,56,179,9,130,2,137,31,148,20,159,205,70,198,77,219,80,208,91,225,106,234,97,247,124,252,119,149,30,158,21,131,8,136,3,185,50,178,57,175,36,164,47,250,113,241,122,236,103,231,108,214,93,221,86,192,75,203,64,162,41,169,34,180,63,191,52,142,5,133,14,152,19,147,24,74,193,65,202,92,215,87,220,102,237,109,230,112,251,123,240,18,153,25,146,4,143,15,132,62,181,53,190,40,163,35,168,135,12,140,7,145,26,154,17,171,32,160,43,189,54,182,61,223,84,212,95,201,66,194,73,243,120,248,115,229,110,238,101,55,188,60,183,33,170,42,161,27,144,16,155,13,134,6,141,111,228,100,239,121,242,114,249,67,200,72,195,85,222,94,213,0,140,5,137,10,134,15,131,20,152,17,157,30,146,27,151,40,164,45,161,34,174,39,171,60,176,57,181,54,186,51,191,80,220,85,217,90,214,95,211,68,200,65,205,78,194,75,199,120,244,125,241,114,254,119,251,108,224,105,229,102,234,99,239,160,44,165,41,170,38,175,35,180,56,177,61,190,50,187,55,136,4,141,1,130,14,135,11,156,16,153,21,150,26,147,31,240,124,245,121,250,118,255,115,228,104,225,109,238,98,235,103,216,84,221,81,210,94,215,91,204,64,201,69,198,74,195,79,93,209,88,212,87,219,82,222,73,197,76,192,67,207,70,202,117,249,112,252,127,243,122,246,97,237,100,232,107,231,110,226,13,129,8,132,7,139,2,142,25,149,28,144,19,159,22,154,37,169,32,172,47,163,42,166,49,189,52,184,59,183,62,178,253,113,248,116,247,123,242,126,233,101,236,96,227,111,230,106,213,89,208,92,223,83,218,86,193,77,196,72,203,71,206,66,173,33,168,36,167,43,162,46,185,53,188,48,179,63,182,58,133,9,128,12,143,3,138,6,145,29,148,24,155,23,158,18,0,141,7,138,14,131,9,132,28,145,27,150,18,159,21,152,56,181,63,178,54,187,49,188,36,169,35,174,42,167,45,160,112,253,119,250,126,243,121,244,108,225,107,230,98,239,101,232,72,197,79,194,70,203,65,204,84,217,83,222,90,215,93,208,224,109,231,106,238,99,233,100,252,113,251,118,242,127,245,120,216,85,223,82,214,91,209,92,196,73,195,78,202,71,205,64,144,29,151,26,158,19,153,20,140,1,139,6,130,15,133,8,168,37,175,34,166,43,161,44,180,57,179,62,186,55,189,48,221,80,218,87,211,94,212,89,193,76,198,75,207,66,200,69,229,104,226,111,235,102,236,97,249,116,254,115,247,122,240,125,173,32,170,39,163,46,164,41,177,60,182,59,191,50,184,53,149,24,146,31,155,22,156,17,137,4,142,3,135,10,128,13,61,176,58,183,51,190,52,185,33,172,38,171,47,162,40,165,5,136,2,143,11,134,12,129,25,148,30,147,23,154,16,157,77,192,74,199,67,206,68,201,81,220,86,219,95,210,88,213,117,248,114,255,123,246,124,241,105,228,110,227,103,234,96,237,0,142,1,143,2,140,3,141,4,138,5,139,6,136,7,137,8,134,9,135,10,132,11,133,12,130,13,131,14,128,15,129,16,158,17,159,18,156,19,157,20,154,21,155,22,152,23,153,24,150,25,151,26,148,27,149,28,146,29,147,30,144,31,145,32,174,33,175,34,172,35,173,36,170,37,171,38,168,39,169,40,166,41,167,42,164,43,165,44,162,45,163,46,160,47,161,48,190,49,191,50,188,51,189,52,186,53,187,54,184,55,185,56,182,57,183,58,180,59,181,60,178,61,179,62,176,63,177,64,206,65,207,66,204,67,205,68,202,69,203,70,200,71,201,72,198,73,199,74,196,75,197,76,194,77,195,78,192,79,193,80,222,81,223,82,220,83,221,84,218,85,219,86,216,87,217,88,214,89,215,90,212,91,213,92,210,93,211,94,208,95,209,96,238,97,239,98,236,99,237,100,234,101,235,102,232,103,233,104,230,105,231,106,228,107,229,108,226,109,227,110,224,111,225,112,254,113,255,114,252,115,253,116,250,117,251,118,248,119,249,120,246,121,247,122,244,123,245,124,242,125,243,126,240,127,241,0,143,3,140,6,137,5,138,12,131,15,128,10,133,9,134,24,151,27,148,30,145,29,146,20,155,23,152,18,157,17,158,48,191,51,188,54,185,53,186,60,179,63,176,58,181,57,182,40,167,43,164,46,161,45,162,36,171,39,168,34,173,33,174,96,239,99,236,102,233,101,234,108,227,111,224,106,229,105,230,120,247,123,244,126,241,125,242,116,251,119,248,114,253,113,254,80,223,83,220,86,217,85,218,92,211,95,208,90,213,89,214,72,199,75,196,78,193,77,194,68,203,71,200,66,205,65,206,192,79,195,76,198,73,197,74,204,67,207,64,202,69,201,70,216,87,219,84,222,81,221,82,212,91,215,88,210,93,209,94,240,127,243,124,246,121,245,122,252,115,255,112,250,117,249,118,232,103,235,100,238,97,237,98,228,107,231,104,226,109,225,110,160,47,163,44,166,41,165,42,172,35,175,32,170,37,169,38,184,55,187,52,190,49,189,50,180,59,183,56,178,61,177,62,144,31,147,28,150,25,149,26,156,19,159,16,154,21,153,22,136,7,139,4,142,1,141,2,132,11,135,8,130,13,129,14,0,144,61,173,122,234,71,215,244,100,201,89,142,30,179,35,245,101,200,88,143,31,178,34,1,145,60,172,123,235,70,214,247,103,202,90,141,29,176,32,3,147,62,174,121,233,68,212,2,146,63,175,120,232,69,213,246,102,203,91,140,28,177,33,243,99,206,94,137,25,180,36,7,151,58,170,125,237,64,208,6,150,59,171,124,236,65,209,242,98,207,95,136,24,181,37,4,148,57,169,126,238,67,211,240,96,205,93,138,26,183,39,241,97,204,92,139,27,182,38,5,149,56,168,127,239,66,210,251,107,198,86,129,17,188,44,15,159,50,162,117,229,72,216,14,158,51,163,116,228,73,217,250,106,199,87,128,16,189,45,12,156,49,161,118,230,75,219,248,104,197,85,130,18,191,47,249,105,196,84,131,19,190,46,13,157,48,160,119,231,74,218,8,152,53,165,114,226,79,223,252,108,193,81,134,22,187,43,253,109,192,80,135,23,186,42,9,153,52,164,115,227,78,222,255,111,194,82,133,21,184,40,11,155,54,166,113,225,76,220,10,154,55,167,112,224,77,221,254,110,195,83,132,20,185,41,0,145,63,174,126,239,65,208,252,109,195,82,130,19,189,44,229,116,218,75,155,10,164,53,25,136,38,183,103,246,88,201,215,70,232,121,169,56,150,7,43,186,20,133,85,196,106,251,50,163,13,156,76,221,115,226,206,95,241,96,176,33,143,30,179,34,140,29,205,92,242,99,79,222,112,225,49,160,14,159,86,199,105,248,40,185,23,134,170,59,149,4,212,69,235,122,100,245,91,202,26,139,37,180,152,9,167,54,230,119,217,72,129,16,190,47,255,110,192,81,125,236,66,211,3,146,60,173,123,234,68,213,5,148,58,171,135,22,184,41,249,104,198,87,158,15,161,48,224,113,223,78,98,243,93,204,28,141,35,178,172,61,147,2,210,67,237,124,80,193,111,254,46,191,17,128,73,216,118,231,55,166,8,153,181,36,138,27,203,90,244,101,200,89,247,102,182,39,137,24,52,165,11,154,74,219,117,228,45,188,18,131,83,194,108,253,209,64,238,127,175,62,144,1,31,142,32,177,97,240,94,207,227,114,220,77,157,12,162,51,250,107,197,84,132,21,187,42,6,151,57,168,120,233,71,214,0,146,57,171,114,224,75,217,228,118,221,79,150,4,175,61,213,71,236,126,167,53,158,12,49,163,8,154,67,209,122,232,183,37,142,28,197,87,252,110,83,193,106,248,33,179,24,138,98,240,91,201,16,130,41,187,134,20,191,45,244,102,205,95,115,225,74,216,1,147,56,170,151,5,174,60,229,119,220,78,166,52,159,13,212,70,237,127,66,208,123,233,48,162,9,155,196,86,253,111,182,36,143,29,32,178,25,139,82,192,107,249,17,131,40,186,99,241,90,200,245,103,204,94,135,21,190,44,230,116,223,77,148,6,173,63,2,144,59,169,112,226,73,219,51,161,10,152,65,211,120,234,215,69,238,124,165,55,156,14,81,195,104,250,35,177,26,136,181,39,140,30,199,85,254,108,132,22,189,47,246,100,207,93,96,242,89,203,18,128,43,185,149,7,172,62,231,117,222,76,113,227,72,218,3,145,58,168,64,210,121,235,50,160,11,153,164,54,157,15,214,68,239,125,34,176,27,137,80,194,105,251,198,84,255,109,180,38,141,31,247,101,206,92,133,23,188,46,19,129,42,184,97,243,88,202,0,147,59,168,118,229,77,222,236,127,215,68,154,9,161,50,197,86,254,109,179,32,136,27,41,186,18,129,95,204,100,247,151,4,172,63,225,114,218,73,123,232,64,211,13,158,54,165,82,193,105,250,36,183,31,140,190,45,133,22,200,91,243,96,51,160,8,155,69,214,126,237,223,76,228,119,169,58,146,1,246,101,205,94,128,19,187,40,26,137,33,178,108,255,87,196,164,55,159,12,210,65,233,122,72,219,115,224,62,173,5,150,97,242,90,201,23,132,44,191,141,30,182,37,251,104,192,83,102,245,93,206,16,131,43,184,138,25,177,34,252,111,199,84,163,48,152,11,213,70,238,125,79,220,116,231,57,170,2,145,241,98,202,89,135,20,188,47,29,142,38,181,107,248,80,195,52,167,15,156,66,209,121,234,216,75,227,112,174,61,149,6,85,198,110,253,35,176,24,139,185,42,130,17,207,92,244,103,144,3,171,56,230,117,221,78,124,239,71,212,10,153,49,162,194,81,249,106,180,39,143,28,46,189,21,134,88,203,99,240,7,148,60,175,113,226,74,217,235,120,208,67,157,14,166,53,0,148,53,161,106,254,95,203,212,64,225,117,190,42,139,31,181,33,128,20,223,75,234,126,97,245,84,192,11,159,62,170,119,227,66,214,29,137,40,188,163,55,150,2,201,93,252,104,194,86,247,99,168,60,157,9,22,130,35,183,124,232,73,221,238,122,219,79,132,16,177,37,58,174,15,155,80,196,101,241,91,207,110,250,49,165,4,144,143,27,186,46,229,113,208,68,153,13,172,56,243,103,198,82,77,217,120,236,39,179,18,134,44,184,25,141,70,210,115,231,248,108,205,89,146,6,167,51,193,85,244,96,171,63,158,10,21,129,32,180,127,235,74,222,116,224,65,213,30,138,43,191,160,52,149,1,202,94,255,107,182,34,131,23,220,72,233,125,98,246,87,195,8,156,61,169,3,151,54,162,105,253,92,200,215,67,226,118,189,41,136,28,47,187,26,142,69,209,112,228,251,111,206,90,145,5,164,48,154,14,175,59,240,100,197,81,78,218,123,239,36,176,17,133,88,204,109,249,50,166,7,147,140,24,185,45,230,114,211,71,237,121,216,76,135,19,178,38,57,173,12,152,83,199,102,242,0,149,55,162,110,251,89,204,220,73,235,126,178,39,133,16,165,48,146,7,203,94,252,105,121,236,78,219,23,130,32,181,87,194,96,245,57,172,14,155,139,30,188,41,229,112,210,71,242,103,197,80,156,9,171,62,46,187,25,140,64,213,119,226,174,59,153,12,192,85,247,98,114,231,69,208,28,137,43,190,11,158,60,169,101,240,82,199,215,66,224,117,185,44,142,27,249,108,206,91,151,2,160,53,37,176,18,135,75,222,124,233,92,201,107,254,50,167,5,144,128,21,183,34,238,123,217,76,65,212,118,227,47,186,24,141,157,8,170,63,243,102,196,81,228,113,211,70,138,31,189,40,56,173,15,154,86,195,97,244,22,131,33,180,120,237,79,218,202,95,253,104,164,49,147,6,179,38,132,17,221,72,234,127,111,250,88,205,1,148,54,163,239,122,216,77,129,20,182,35,51,166,4,145,93,200,106,255,74,223,125,232,36,177,19,134,150,3,161,52,248,109,207,90,184,45,143,26,214,67,225,116,100,241,83,198,10,159,61,168,29,136,42,191,115,230,68,209,193,84,246,99,175,58,152,13,0,150,49,167,98,244,83,197,196,82,245,99,166,48,151,1,149,3,164,50,247,97,198,80,81,199,96,246,51,165,2,148,55,161,6,144,85,195,100,242,243,101,194,84,145,7,160,54,162,52,147,5,192,86,241,103,102,240,87,193,4,146,53,163,110,248,95,201,12,154,61,171,170,60,155,13,200,94,249,111,251,109,202,92,153,15,168,62,63,169,14,152,93,203,108,250,89,207,104,254,59,173,10,156,157,11,172,58,255,105,206,88,204,90,253,107,174,56,159,9,8,158,57,175,106,252,91,205,220,74,237,123,190,40,143,25,24,142,41,191,122,236,75,221,73,223,120,238,43,189,26,140,141,27,188,42,239,121,222,72,235,125,218,76,137,31,184,46,47,185,30,136,77,219,124,234,126,232,79,217,28,138,45,187,186,44,139,29,216,78,233,127,178,36,131,21,208,70,225,119,118,224,71,209,20,130,37,179,39,177,22,128,69,211,116,226,227,117,210,68,129,23,176,38,133,19,180,34,231,113,214,64,65,215,112,230,35,181,18,132,16,134,33,183,114,228,67,213,212,66,229,115,182,32,135,17,0,151,51,164,102,241,85,194,204,91,255,104,170,61,153,14,133,18,182,33,227,116,208,71,73,222,122,237,47,184,28,139,23,128,36,179,113,230,66,213,219,76,232,127,189,42,142,25,146,5,161,54,244,99,199,80,94,201,109,250,56,175,11,156,46,185,29,138,72,223,123,236,226,117,209,70,132,19,183,32,171,60,152,15,205,90,254,105,103,240,84,195,1,150,50,165,57,174,10,157,95,200,108,251,245,98,198,81,147,4,160,55,188,43,143,24,218,77,233,126,112,231,67,212,22,129,37,178,92,203,111,248,58,173,9,158,144,7,163,52,246,97,197,82,217,78,234,125,191,40,140,27,21,130,38,177,115,228,64,215,75,220,120,239,45,186,30,137,135,16,180,35,225,118,210,69,206,89,253,106,168,63,155,12,2,149,49,166,100,243,87,192,114,229,65,214,20,131,39,176,190,41,141,26,216,79,235,124,247,96,196,83,145,6,162,53,59,172,8,159,93,202,110,249,101,242,86,193,3,148,48,167,169,62,154,13,207,88,252,107,224,119,211,68,134,17,181,34,44,187,31,136,74,221,121,238,0,152,45,181,90,194,119,239,180,44,153,1,238,118,195,91,117,237,88,192,47,183,2,154,193,89,236,116,155,3,182,46,234,114,199,95,176,40,157,5,94,198,115,235,4,156,41,177,159,7,178,42,197,93,232,112,43,179,6,158,113,233,92,196,201,81,228,124,147,11,190,38,125,229,80,200,39,191,10,146,188,36,145,9,230,126,203,83,8,144,37,189,82,202,127,231,35,187,14,150,121,225,84,204,151,15,186,34,205,85,224,120,86,206,123,227,12,148,33,185,226,122,207,87,184,32,149,13,143,23,162,58,213,77,248,96,59,163,22,142,97,249,76,212,250,98,215,79,160,56,141,21,78,214,99,251,20,140,57,161,101,253,72,208,63,167,18,138,209,73,252,100,139,19,166,62,16,136,61,165,74,210,103,255,164,60,137,17,254,102,211,75,70,222,107,243,28,132,49,169,242,106,223,71,168,48,133,29,51,171,30,134,105,241,68,220,135,31,170,50,221,69,240,104,172,52,129,25,246,110,219,67,24,128,53,173,66,218,111,247,217,65,244,108,131,27,174,54,109,245,64,216,55,175,26,130,0,153,47,182,94,199,113,232,188,37,147,10,226,123,205,84,101,252,74,211,59,162,20,141,217,64,246,111,135,30,168,49,202,83,229,124,148,13,187,34,118,239,89,192,40,177,7,158,175,54,128,25,241,104,222,71,19,138,60,165,77,212,98,251,137,16,166,63,215,78,248,97,53,172,26,131,107,242,68,221,236,117,195,90,178,43,157,4,80,201,127,230,14,151,33,184,67,218,108,245,29,132,50,171,255,102,208,73,161,56,142,23,38,191,9,144,120,225,87,206,154,3,181,44,196,93,235,114,15,150,32,185,81,200,126,231,179,42,156,5,237,116,194,91,106,243,69,220,52,173,27,130,214,79,249,96,136,17,167,62,197,92,234,115,155,2,180,45,121,224,86,207,39,190,8,145,160,57,143,22,254,103,209,72,28,133,51,170,66,219,109,244,134,31,169,48,216,65,247,110,58,163,21,140,100,253,75,210,227,122,204,85,189,36,146,11,95,198,112,233,1,152,46,183,76,213,99,250,18,139,61,164,240,105,223,70,174,55,129,24,41,176,6,159,119,238,88,193,149,12,186,35,203,82,228,125,0,154,41,179,82,200,123,225,164,62,141,23,246,108,223,69,85,207,124,230,7,157,46,180,241,107,216,66,163,57,138,16,170,48,131,25,248,98,209,75,14,148,39,189,92,198,117,239,255,101,214,76,173,55,132,30,91,193,114,232,9,147,32,186,73,211,96,250,27,129,50,168,237,119,196,94,191,37,150,12,28,134,53,175,78,212,103,253,184,34,145,11,234,112,195,89,227,121,202,80,177,43,152,2,71,221,110,244,21,143,60,166,182,44,159,5,228,126,205,87,18,136,59,161,64,218,105,243,146,8,187,33,192,90,233,115,54,172,31,133,100,254,77,215,199,93,238,116,149,15,188,38,99,249,74,208,49,171,24,130,56,162,17,139,106,240,67,217,156,6,181,47,206,84,231,125,109,247,68,222,63,165,22,140,201,83,224,122,155,1,178,40,219,65,242,104,137,19,160,58,127,229,86,204,45,183,4,158,142,20,167,61,220,70,245,111,42,176,3,153,120,226,81,203,113,235,88,194,35,185,10,144,213,79,252,102,135,29,174,52,36,190,13,151,118,236,95,197,128,26,169,51,210,72,251,97,0,155,43,176,86,205,125,230,172,55,135,28,250,97,209,74,69,222,110,245,19,136,56,163,233,114,194,89,191,36,148,15,138,17,161,58,220,71,247,108,38,189,13,150,112,235,91,192,207,84,228,127,153,2,178,41,99,248,72,211,53,174,30,133,9,146,34,185,95,196,116,239,165,62,142,21,243,104,216,67,76,215,103,252,26,129,49,170,224,123,203,80,182,45,157,6,131,24,168,51,213,78,254,101,47,180,4,159,121,226,82,201,198,93,237,118,144,11,187,32,106,241,65,218,60,167,23,140,18,137,57,162,68,223,111,244,190,37,149,14,232,115,195,88,87,204,124,231,1,154,42,177,251,96,208,75,173,54,134,29,152,3,179,40,206,85,229,126,52,175,31,132,98,249,73,210,221,70,246,109,139,16,160,59,113,234,90,193,39,188,12,151,27,128,48,171,77,214,102,253,183,44,156,7,225,122,202,81,94,197,117,238,8,147,35,184,242,105,217,66,164,63,143,20,145,10,186,33,199,92,236,119,61,166,22,141,107,240,64,219,212,79,255,100,130,25,169,50,120,227,83,200,46,181,5,158,0,156,37,185,74,214,111,243,148,8,177,45,222,66,251,103,53,169,16,140,127,227,90,198,161,61,132,24,235,119,206,82,106,246,79,211,32,188,5,153,254,98,219,71,180,40,145,13,95,195,122,230,21,137,48,172,203,87,238,114,129,29,164,56,212,72,241,109,158,2,187,39,64,220,101,249,10,150,47,179,225,125,196,88,171,55,142,18,117,233,80,204,63,163,26,134,190,34,155,7,244,104,209,77,42,182,15,147,96,252,69,217,139,23,174,50,193,93,228,120,31,131,58,166,85,201,112,236,181,41,144,12,255,99,218,70,33,189,4,152,107,247,78,210,128,28,165,57,202,86,239,115,20,136,49,173,94,194,123,231,223,67,250,102,149,9,176,44,75,215,110,242,1,157,36,184,234,118,207,83,160,60,133,25,126,226,91,199,52,168,17,141,97,253,68,216,43,183,14,146,245,105,208,76,191,35,154,6,84,200,113,237,30,130,59,167,192,92,229,121,138,22,175,51,11,151,46,178,65,221,100,248,159,3,186,38,213,73,240,108,62,162,27,135,116,232,81,205,170,54,143,19,224,124,197,89,0,157,39,186,78,211,105,244,156,1,187,38,210,79,245,104,37,184,2,159,107,246,76,209,185,36,158,3,247,106,208,77,74,215,109,240,4,153,35,190,214,75,241,108,152,5,191,34,111,242,72,213,33,188,6,155,243,110,212,73,189,32,154,7,148,9,179,46,218,71,253,96,8,149,47,178,70,219,97,252,177,44,150,11,255,98,216,69,45,176,10,151,99,254,68,217,222,67,249,100,144,13,183,42,66,223,101,248,12,145,43,182,251,102,220,65,181,40,146,15,103,250,64,221,41,180,14,147,53,168,18,143,123,230,92,193,169,52,142,19,231,122,192,93,16,141,55,170,94,195,121,228,140,17,171,54,194,95,229,120,127,226,88,197,49,172,22,139,227,126,196,89,173,48,138,23,90,199,125,224,20,137,51,174,198,91,225,124,136,21,175,50,161,60,134,27,239,114,200,85,61,160,26,135,115,238,84,201,132,25,163,62,202,87,237,112,24,133,63,162,86,203,113,236,235,118,204,81,165,56,130,31,119,234,80,205,57,164,30,131,206,83,233,116,128,29,167,58,82,207,117,232,28,129,59,166,0,158,33,191,66,220,99,253,132,26,165,59,198,88,231,121,21,139,52,170,87,201,118,232,145,15,176,46,211,77,242,108,42,180,11,149,104,246,73,215,174,48,143,17,236,114,205,83,63,161,30,128,125,227,92,194,187,37,154,4,249,103,216,70,84,202,117,235,22,136,55,169,208,78,241,111,146,12,179,45,65,223,96,254,3,157,34,188,197,91,228,122,135,25,166,56,126,224,95,193,60,162,29,131,250,100,219,69,184,38,153,7,107,245,74,212,41,183,8,150,239,113,206,80,173,51,140,18,168,54,137,23,234,116,203,85,44,178,13,147,110,240,79,209,189,35,156,2,255,97,222,64,57,167,24,134,123,229,90,196,130,28,163,61,192,94,225,127,6,152,39,185,68,218,101,251,151,9,182,40,213,75,244,106,19,141,50,172,81,207,112,238,252,98,221,67,190,32,159,1,120,230,89,199,58,164,27,133,233,119,200,86,171,53,138,20,109,243,76,210,47,177,14,144,214,72,247,105,148,10,181,43,82,204,115,237,16,142,49,175,195,93,226,124,129,31,160,62,71,217,102,248,5,155,36,186,0,159,35,188,70,217,101,250,140,19,175,48,202,85,233,118,5,154,38,185,67,220,96,255,137,22,170,53,207,80,236,115,10,149,41,182,76,211,111,240,134,25,165,58,192,95,227,124,15,144,44,179,73,214,106,245,131,28,160,63,197,90,230,121,20,139,55,168,82,205,113,238,152,7,187,36,222,65,253,98,17,142,50,173,87,200,116,235,157,2,190,33,219,68,248,103,30,129,61,162,88,199,123,228,146,13,177,46,212,75,247,104,27,132,56,167,93,194,126,225,151,8,180,43,209,78,242,109,40,183,11,148,110,241,77,210,164,59,135,24,226,125,193,94,45,178,14,145,107,244,72,215,161,62,130,29,231,120,196,91,34,189,1,158,100,251,71,216,174,49,141,18,232,119,203,84,39,184,4,155,97,254,66,221,171,52,136,23,237,114,206,81,60,163,31,128,122,229,89,198,176,47,147,12,246,105,213,74,57,166,26,133,127,224,92,195,181,42,150,9,243,108,208,79,54,169,21,138,112,239,83,204,186,37,153,6,252,99,223,64,51,172,16,143,117,234,86,201,191,32,156,3,249,102,218,69,0,160,93,253,186,26,231,71,105,201,52,148,211,115,142,46,210,114,143,47,104,200,53,149,187,27,230,70,1,161,92,252,185,25,228,68,3,163,94,254,208,112,141,45,106,202,55,151,107,203,54,150,209,113,140,44,2,162,95,255,184,24,229,69,111,207,50,146,213,117,136,40,6,166,91,251,188,28,225,65,189,29,224,64,7,167,90,250,212,116,137,41,110,206,51,147,214,118,139,43,108,204,49,145,191,31,226,66,5,165,88,248,4,164,89,249,190,30,227,67,109,205,48,144,215,119,138,42,222,126,131,35,100,196,57,153,183,23,234,74,13,173,80,240,12,172,81,241,182,22,235,75,101,197,56,152,223,127,130,34,103,199,58,154,221,125,128,32,14,174,83,243,180,20,233,73,181,21,232,72,15,175,82,242,220,124,129,33,102,198,59,155,177,17,236,76,11,171,86,246,216,120,133,37,98,194,63,159,99,195,62,158,217,121,132,36,10,170,87,247,176,16,237,77,8,168,85,245,178,18,239,79,97,193,60,156,219,123,134,38,218,122,135,39,96,192,61,157,179,19,238,78,9,169,84,244,0,161,95,254,190,31,225,64,97,192,62,159,223,126,128,33,194,99,157,60,124,221,35,130,163,2,252,93,29,188,66,227,153,56,198,103,39,134,120,217,248,89,167,6,70,231,25,184,91,250,4,165,229,68,186,27,58,155,101,196,132,37,219,122,47,142,112,209,145,48,206,111,78,239,17,176,240,81,175,14,237,76,178,19,83,242,12,173,140,45,211,114,50,147,109,204,182,23,233,72,8,169,87,246,215,118,136,41,105,200,54,151,116,213,43,138,202,107,149,52,21,180,74,235,171,10,244,85,94,255,1,160,224,65,191,30,63,158,96,193,129,32,222,127,156,61,195,98,34,131,125,220,253,92,162,3,67,226,28,189,199,102,152,57,121,216,38,135,166,7,249,88,24,185,71,230,5,164,90,251,187,26,228,69,100,197,59,154,218,123,133,36,113,208,46,143,207,110,144,49,16,177,79,238,174,15,241,80,179,18,236,77,13,172,82,243,210,115,141,44,108,205,51,146,232,73,183,22,86,247,9,168,137,40,214,119,55,150,104,201,42,139,117,212,148,53,203,106,75,234,20,181,245,84,170,11,0,162,89,251,178,16,235,73,121,219,32,130,203,105,146,48,242,80,171,9,64,226,25,187,139,41,210,112,57,155,96,194,249,91,160,2,75,233,18,176,128,34,217,123,50,144,107,201,11,169,82,240,185,27,224,66,114,208,43,137,192,98,153,59,239,77,182,20,93,255,4,166,150,52,207,109,36,134,125,223,29,191,68,230,175,13,246,84,100,198,61,159,214,116,143,45,22,180,79,237,164,6,253,95,111,205,54,148,221,127,132,38,228,70,189,31,86,244,15,173,157,63,196,102,47,141,118,212,195,97,154,56,113,211,40,138,186,24,227,65,8,170,81,243,49,147,104,202,131,33,218,120,72,234,17,179,250,88,163,1,58,152,99,193,136,42,209,115,67,225,26,184,241,83,168,10,200,106,145,51,122,216,35,129,177,19,232,74,3,161,90,248,44,142,117,215,158,60,199,101,85,247,12,174,231,69,190,28,222,124,135,37,108,206,53,151,167,5,254,92,21,183,76,238,213,119,140,46,103,197,62,156,172,14,245,87,30,188,71,229,39,133,126,220,149,55,204,110,94,252,7,165,236,78,181,23,0,163,91,248,182,21,237,78,113,210,42,137,199,100,156,63,226,65,185,26,84,247,15,172,147,48,200,107,37,134,126,221,217,122,130,33,111,204,52,151,168,11,243,80,30,189,69,230,59,152,96,195,141,46,214,117,74,233,17,178,252,95,167,4,175,12,244,87,25,186,66,225,222,125,133,38,104,203,51,144,77,238,22,181,251,88,160,3,60,159,103,196,138,41,209,114,118,213,45,142,192,99,155,56,7,164,92,255,177,18,234,73,148,55,207,108,34,129,121,218,229,70,190,29,83,240,8,171,67,224,24,187,245,86,174,13,50,145,105,202,132,39,223,124,161,2,250,89,23,180,76,239,208,115,139,40,102,197,61,158,154,57,193,98,44,143,119,212,235,72,176,19,93,254,6,165,120,219,35,128,206,109,149,54,9,170,82,241,191,28,228,71,236,79,183,20,90,249,1,162,157,62,198,101,43,136,112,211,14,173,85,246,184,27,227,64,127,220,36,135,201,106,146,49,53,150,110,205,131,32,216,123,68,231,31,188,242,81,169,10,215,116,140,47,97,194,58,153,166,5,253,94,16,179,75,232,0,164,85,241,170,14,255,91,73,237,28,184,227,71,182,18,146,54,199,99,56,156,109,201,219,127,142,42,113,213,36,128,57,157,108,200,147,55,198,98,112,212,37,129,218,126,143,43,171,15,254,90,1,165,84,240,226,70,183,19,72,236,29,185,114,214,39,131,216,124,141,41,59,159,110,202,145,53,196,96,224,68,181,17,74,238,31,187,169,13,252,88,3,167,86,242,75,239,30,186,225,69,180,16,2,166,87,243,168,12,253,89,217,125,140,40,115,215,38,130,144,52,197,97,58,158,111,203,228,64,177,21,78,234,27,191,173,9,248,92,7,163,82,246,118,210,35,135,220,120,137,45,63,155,106,206,149,49,192,100,221,121,136,44,119,211,34,134,148,48,193,101,62,154,107,207,79,235,26,190,229,65,176,20,6,162,83,247,172,8,249,93,150,50,195,103,60,152,105,205,223,123,138,46,117,209,32,132,4,160,81,245,174,10,251,95,77,233,24,188,231,67,178,22,175,11,250,94,5,161,80,244,230,66,179,23,76,232,25,189,61,153,104,204,151,51,194,102,116,208,33,133,222,122,139,47,0,165,87,242,174,11,249,92,65,228,22,179,239,74,184,29,130,39,213,112,44,137,123,222,195,102,148,49,109,200,58,159,25,188,78,235,183,18,224,69,88,253,15,170,246,83,161,4,155,62,204,105,53,144,98,199,218,127,141,40,116,209,35,134,50,151,101,192,156,57,203,110,115,214,36,129,221,120,138,47,176,21,231,66,30,187,73,236,241,84,166,3,95,250,8,173,43,142,124,217,133,32,210,119,106,207,61,152,196,97,147,54,169,12,254,91,7,162,80,245,232,77,191,26,70,227,17,180,100,193,51,150,202,111,157,56,37,128,114,215,139,46,220,121,230,67,177,20,72,237,31,186,167,2,240,85,9,172,94,251,125,216,42,143,211,118,132,33,60,153,107,206,146,55,197,96,255,90,168,13,81,244,6,163,190,27,233,76,16,181,71,226,86,243,1,164,248,93,175,10,23,178,64,229,185,28,238,75,212,113,131,38,122,223,45,136,149,48,194,103,59,158,108,201,79,234,24,189,225,68,182,19,14,171,89,252,160,5,247,82,205,104,154,63,99,198,52,145,140,41,219,126,34,135,117,208,0,166,81,247,162,4,243,85,89,255,8,174,251,93,170,12,178,20,227,69,16,182,65,231,235,77,186,28,73,239,24,190,121,223,40,142,219,125,138,44,32,134,113,215,130,36,211,117,203,109,154,60,105,207,56,158,146,52,195,101,48,150,97,199,242,84,163,5,80,246,1,167,171,13,250,92,9,175,88,254,64,230,17,183,226,68,179,21,25,191,72,238,187,29,234,76,139,45,218,124,41,143,120,222,210,116,131,37,112,214,33,135,57,159,104,206,155,61,202,108,96,198,49,151,194,100,147,53,249,95,168,14,91,253,10,172,160,6,241,87,2,164,83,245,75,237,26,188,233,79,184,30,18,180,67,229,176,22,225,71,128,38,209,119,34,132,115,213,217,127,136,46,123,221,42,140,50,148,99,197,144,54,193,103,107,205,58,156,201,111,152,62,11,173,90,252,169,15,248,94,82,244,3,165,240,86,161,7,185,31,232,78,27,189,74,236,224,70,177,23,66,228,19,181,114,212,35,133,208,118,129,39,43,141,122,220,137,47,216,126,192,102,145,55,98,196,51,149,153,63,200,110,59,157,106,204,0,167,83,244,166,1,245,82,81,246,2,165,247,80,164,3,162,5,241,86,4,163,87,240,243,84,160,7,85,242,6,161,89,254,10,173,255,88,172,11,8,175,91,252,174,9,253,90,251,92,168,15,93,250,14,169,170,13,249,94,12,171,95,248,178,21,225,70,20,179,71,224,227,68,176,23,69,226,22,177,16,183,67,228,182,17,229,66,65,230,18,181,231,64,180,19,235,76,184,31,77,234,30,185,186,29,233,78,28,187,79,232,73,238,26,189,239,72,188,27,24,191,75,236,190,25,237,74,121,222,42,141,223,120,140,43,40,143,123,220,142,41,221,122,219,124,136,47,125,218,46,137,138,45,217,126,44,139,127,216,32,135,115,212,134,33,213,114,113,214,34,133,215,112,132,35,130,37,209,118,36,131,119,208,211,116,128,39,117,210,38,129,203,108,152,63,109,202,62,153,154,61,201,110,60,155,111,200,105,206,58,157,207,104,156,59,56,159,107,204,158,57,205,106,146,53,193,102,52,147,103,192,195,100,144,55,101,194,54,145,48,151,99,196,150,49,197,98,97,198,50,149,199,96,148,51,0,168,77,229,154,50,215,127,41,129,100,204,179,27,254,86,82,250,31,183,200,96,133,45,123,211,54,158,225,73,172,4,164,12,233,65,62,150,115,219,141,37,192,104,23,191,90,242,246,94,187,19,108,196,33,137,223,119,146,58,69,237,8,160,85,253,24,176,207,103,130,42,124,212,49,153,230,78,171,3,7,175,74,226,157,53,208,120,46,134,99,203,180,28,249,81,241,89,188,20,107,195,38,142,216,112,149,61,66,234,15,167,163,11,238,70,57,145,116,220,138,34,199,111,16,184,93,245,170,2,231,79,48,152,125,213,131,43,206,102,25,177,84,252,248,80,181,29,98,202,47,135,209,121,156,52,75,227,6,174,14,166,67,235,148,60,217,113,39,143,106,194,189,21,240,88,92,244,17,185,198,110,139,35,117,221,56,144,239,71,162,10,255,87,178,26,101,205,40,128,214,126,155,51,76,228,1,169,173,5,224,72,55,159,122,210,132,44,201,97,30,182,83,251,91,243,22,190,193,105,140,36,114,218,63,151,232,64,165,13,9,161,68,236,147,59,222,118,32,136,109,197,186,18,247,95,0,169,79,230,158,55,209,120,33,136,110,199,191,22,240,89,66,235,13,164,220,117,147,58,99,202,44,133,253,84,178,27,132,45,203,98,26,179,85,252,165,12,234,67,59,146,116,221,198,111,137,32,88,241,23,190,231,78,168,1,121,208,54,159,21,188,90,243,139,34,196,109,52,157,123,210,170,3,229,76,87,254,24,177,201,96,134,47,118,223,57,144,232,65,167,14,145,56,222,119,15,166,64,233,176,25,255,86,46,135,97,200,211,122,156,53,77,228,2,171,242,91,189,20,108,197,35,138,42,131,101,204,180,29,251,82,11,162,68,237,149,60,218,115,104,193,39,142,246,95,185,16,73,224,6,175,215,126,152,49,174,7,225,72,48,153,127,214,143,38,192,105,17,184,94,247,236,69,163,10,114,219,61,148,205,100,130,43,83,250,28,181,63,150,112,217,161,8,238,71,30,183,81,248,128,41,207,102,125,212,50,155,227,74,172,5,92,245,19,186,194,107,141,36,187,18,244,93,37,140,106,195,154,51,213,124,4,173,75,226,249,80,182,31,103,206,40,129,216,113,151,62,70,239,9,160,0,170,73,227,146,56,219,113,57,147,112,218,171,1,226,72,114,216,59,145,224,74,169,3,75,225,2,168,217,115,144,58,228,78,173,7,118,220,63,149,221,119,148,62,79,229,6,172,150,60,223,117,4,174,77,231,175,5,230,76,61,151,116,222,213,127,156,54,71,237,14,164,236,70,165,15,126,212,55,157,167,13,238,68,53,159,124,214,158,52,215,125,12,166,69,239,49,155,120,210,163,9,234,64,8,162,65,235,154,48,211,121,67,233,10,160,209,123,152,50,122,208,51,153,232,66,161,11,183,29,254,84,37,143,108,198,142,36,199,109,28,182,85,255,197,111,140,38,87,253,30,180,252,86,181,31,110,196,39,141,83,249,26,176,193,107,136,34,106,192,35,137,248,82,177,27,33,139,104,194,179,25,250,80,24,178,81,251,138,32,195,105,98,200,43,129,240,90,185,19,91,241,18,184,201,99,128,42,16,186,89,243,130,40,203,97,41,131,96,202,187,17,242,88,134,44,207,101,20,190,93,247,191,21,246,92,45,135,100,206,244,94,189,23,102,204,47,133,205,103,132,46,95,245,22,188,0,171,75,224,150,61,221,118,49,154,122,209,167,12,236,71,98,201,41,130,244,95,191,20,83,248,24,179,197,110,142,37,196,111,143,36,82,249,25,178,245,94,190,21,99,200,40,131,166,13,237,70,48,155,123,208,151,60,220,119,1,170,74,225,149,62,222,117,3,168,72,227,164,15,239,68,50,153,121,210,247,92,188,23,97,202,42,129,198,109,141,38,80,251,27,176,81,250,26,177,199,108,140,39,96,203,43,128,246,93,189,22,51,152,120,211,165,14,238,69,2,169,73,226,148,63,223,116,55,156,124,215,161,10,234,65,6,173,77,230,144,59,219,112,85,254,30,181,195,104,136,35,100,207,47,132,242,89,185,18,243,88,184,19,101,206,46,133,194,105,137,34,84,255,31,180,145,58,218,113,7,172,76,231,160,11,235,64,54,157,125,214,162,9,233,66,52,159,127,212,147,56,216,115,5,174,78,229,192,107,139,32,86,253,29,182,241,90,186,17,103,204,44,135,102,205,45,134,240,91,187,16,87,252,28,183,193,106,138,33,4,175,79,228,146,57,217,114,53,158,126,213,163,8,232,67,0,172,69,233,138,38,207,99,9,165,76,224,131,47,198,106,18,190,87,251,152,52,221,113,27,183,94,242,145,61,212,120,36,136,97,205,174,2,235,71,45,129,104,196,167,11,226,78,54,154,115,223,188,16,249,85,63,147,122,214,181,25,240,92,72,228,13,161,194,110,135,43,65,237,4,168,203,103,142,34,90,246,31,179,208,124,149,57,83,255,22,186,217,117,156,48,108,192,41,133,230,74,163,15,101,201,32,140,239,67,170,6,126,210,59,151,244,88,177,29,119,219,50,158,253,81,184,20,144,60,213,121,26,182,95,243,153,53,220,112,19,191,86,250,130,46,199,107,8,164,77,225,139,39,206,98,1,173,68,232,180,24,241,93,62,146,123,215,189,17,248,84,55,155,114,222,166,10,227,79,44,128,105,197,175,3,234,70,37,137,96,204,216,116,157,49,82,254,23,187,209,125,148,56,91,247,30,178,202,102,143,35,64,236,5,169,195,111,134,42,73,229,12,160,252,80,185,21,118,218,51,159,245,89,176,28,127,211,58,150,238,66,171,7,100,200,33,141,231,75,162,14,109,193,40,132,0,173,71,234,142,35,201,100,1,172,70,235,143,34,200,101,2,175,69,232,140,33,203,102,3,174,68,233,141,32,202,103,4,169,67,238,138,39,205,96,5,168,66,239,139,38,204,97,6,171,65,236,136,37,207,98,7,170,64,237,137,36,206,99,8,165,79,226,134,43,193,108,9,164,78,227,135,42,192,109,10,167,77,224,132,41,195,110,11,166,76,225,133,40,194,111,12,161,75,230,130,47,197,104,13,160,74,231,131,46,196,105,14,163,73,228,128,45,199,106,15,162,72,229,129,44,198,107,16,189,87,250,158,51,217,116,17,188,86,251,159,50,216,117,18,191,85,248,156,49,219,118,19,190,84,249,157,48,218,119,20,185,83,254,154,55,221,112,21,184,82,255,155,54,220,113,22,187,81,252,152,53,223,114,23,186,80,253,153,52,222,115,24,181,95,242,150,59,209,124,25,180,94,243,151,58,208,125,26,183,93,240,148,57,211,126,27,182,92,241,149,56,210,127,28,177,91,246,146,63,213,120,29,176,90,247,147,62,212,121,30,179,89,244,144,61,215,122,31,178,88,245,145,60,214,123,0,174,65,239,130,44,195,109,25,183,88,246,155,53,218,116,50,156,115,221,176,30,241,95,43,133,106,196,169,7,232,70,100,202,37,139,230,72,167,9,125,211,60,146,255,81,190,16,86,248,23,185,212,122,149,59,79,225,14,160,205,99,140,34,200,102,137,39,74,228,11,165,209,127,144,62,83,253,18,188,250,84,187,21,120,214,57,151,227,77,162,12,97,207,32,142,172,2,237,67,46,128,111,193,181,27,244,90,55,153,118,216,158,48,223,113,28,178,93,243,135,41,198,104,5,171,68,234,141,35,204,98,15,161,78,224,148,58,213,123,22,184,87,249,191,17,254,80,61,147,124,210,166,8,231,73,36,138,101,203,233,71,168,6,107,197,42,132,240,94,177,31,114,220,51,157,219,117,154,52,89,247,24,182,194,108,131,45,64,238,1,175,69,235,4,170,199,105,134,40,92,242,29,179,222,112,159,49,119,217,54,152,245,91,180,26,110,192,47,129,236,66,173,3,33,143,96,206,163,13,226,76,56,150,121,215,186,20,251,85,19,189,82,252,145,63,208,126,10,164,75,229,136,38,201,103,0,175,67,236,134,41,197,106,17,190,82,253,151,56,212,123,34,141,97,206,164,11,231,72,51,156,112,223,181,26,246,89,68,235,7,168,194,109,129,46,85,250,22,185,211,124,144,63,102,201,37,138,224,79,163,12,119,216,52,155,241,94,178,29,136,39,203,100,14,161,77,226,153,54,218,117,31,176,92,243,170,5,233,70,44,131,111,192,187,20,248,87,61,146,126,209,204,99,143,32,74,229,9,166,221,114,158,49,91,244,24,183,238,65,173,2,104,199,43,132,255,80,188,19,121,214,58,149,13,162,78,225,139,36,200,103,28,179,95,240,154,53,217,118,47,128,108,195,169,6,234,69,62,145,125,210,184,23,251,84,73,230,10,165,207,96,140,35,88,247,27,180,222,113,157,50,107,196,40,135,237,66,174,1,122,213,57,150,252,83,191,16,133,42,198,105,3,172,64,239,148,59,215,120,18,189,81,254,167,8,228,75,33,142,98,205,182,25,245,90,48,159,115,220,193,110,130,45,71,232,4,171,208,127,147,60,86,249,21,186,227,76,160,15,101,202,38,137,242,93,177,30,116,219,55,152,0,176,125,205,250,74,135,55,233,89,148,36,19,163,110,222,207,127,178,2,53,133,72,248,38,150,91,235,220,108,161,17,131,51,254,78,121,201,4,180,106,218,23,167,144,32,237,93,76,252,49,129,182,6,203,123,165,21,216,104,95,239,34,146,27,171,102,214,225,81,156,44,242,66,143,63,8,184,117,197,212,100,169,25,46,158,83,227,61,141,64,240,199,119,186,10,152,40,229,85,98,210,31,175,113,193,12,188,139,59,246,70,87,231,42,154,173,29,208,96,190,14,195,115,68,244,57,137,54,134,75,251,204,124,177,1,223,111,162,18,37,149,88,232,249,73,132,52,3,179,126,206,16,160,109,221,234,90,151,39,181,5,200,120,79,255,50,130,92,236,33,145,166,22,219,107,122,202,7,183,128,48,253,77,147,35,238,94,105,217,20,164,45,157,80,224,215,103,170,26,196,116,185,9,62,142,67,243,226,82,159,47,24,168,101,213,11,187,118,198,241,65,140,60,174,30,211,99,84,228,41,153,71,247,58,138,189,13,192,112,97,209,28,172,155,43,230,86,136,56,245,69,114,194,15,191,0,177,127,206,254,79,129,48,225,80,158,47,31,174,96,209,223,110,160,17,33,144,94,239,62,143,65,240,192,113,191,14,163,18,220,109,93,236,34,147,66,243,61,140,188,13,195,114,124,205,3,178,130,51,253,76,157,44,226,83,99,210,28,173,91,234,36,149,165,20,218,107,186,11,197,116,68,245,59,138,132,53,251,74,122,203,5,180,101,212,26,171,155,42,228,85,248,73,135,54,6,183,121,200,25,168,102,215,231,86,152,41,39,150,88,233,217,104,166,23,198,119,185,8,56,137,71,246,182,7,201,120,72,249,55,134,87,230,40,153,169,24,214,103,105,216,22,167,151,38,232,89,136,57,247,70,118,199,9,184,21,164,106,219,235,90,148,37,244,69,139,58,10,187,117,196,202,123,181,4,52,133,75,250,43,154,84,229,213,100,170,27,237,92,146,35,19,162,108,221,12,189,115,194,242,67,141,60,50,131,77,252,204,125,179,2,211,98,172,29,45,156,82,227,78,255,49,128,176,1,207,126,175,30,208,97,81,224,46,159,145,32,238,95,111,222,16,161,112,193,15,190,142,63,241,64,0,178,121,203,242,64,139,57,249,75,128,50,11,185,114,192,239,93,150,36,29,175,100,214,22,164,111,221,228,86,157,47,195,113,186,8,49,131,72,250,58,136,67,241,200,122,177,3,44,158,85,231,222,108,167,21,213,103,172,30,39,149,94,236,155,41,226,80,105,219,16,162,98,208,27,169,144,34,233,91,116,198,13,191,134,52,255,77,141,63,244,70,127,205,6,180,88,234,33,147,170,24,211,97,161,19,216,106,83,225,42,152,183,5,206,124,69,247,60,142,78,252,55,133,188,14,197,119,43,153,82,224,217,107,160,18,210,96,171,25,32,146,89,235,196,118,189,15,54,132,79,253,61,143,68,246,207,125,182,4,232,90,145,35,26,168,99,209,17,163,104,218,227,81,154,40,7,181,126,204,245,71,140,62,254,76,135,53,12,190,117,199,176,2,201,123,66,240,59,137,73,251,48,130,187,9,194,112,95,237,38,148,173,31,212,102,166,20,223,109,84,230,45,159,115,193,10,184,129,51,248,74,138,56,243,65,120,202,1,179,156,46,229,87,110,220,23,165,101,215,28,174,151,37,238,92,0,179,123,200,246,69,141,62,241,66,138,57,7,180,124,207,255,76,132,55,9,186,114,193,14,189,117,198,248,75,131,48,227,80,152,43,21,166,110,221,18,161,105,218,228,87,159,44,28,175,103,212,234,89,145,34,237,94,150,37,27,168,96,211,219,104,160,19,45,158,86,229,42,153,81,226,220,111,167,20,36,151,95,236,210,97,169,26,213,102,174,29,35,144,88,235,56,139,67,240,206,125,181,6,201,122,178,1,63,140,68,247,199,116,188,15,49,130,74,249,54,133,77,254,192,115,187,8,171,24,208,99,93,238,38,149,90,233,33,146,172,31,215,100,84,231,47,156,162,17,217,106,165,22,222,109,83,224,40,155,72,251,51,128,190,13,197,118,185,10,194,113,79,252,52,135,183,4,204,127,65,242,58,137,70,245,61,142,176,3,203,120,112,195,11,184,134,53,253,78,129,50,250,73,119,196,12,191,143,60,244,71,121,202,2,177,126,205,5,182,136,59,243,64,147,32,232,91,101,214,30,173,98,209,25,170,148,39,239,92,108,223,23,164,154,41,225,82,157,46,230,85,107,216,16,163,0,180,117,193,234,94,159,43,201,125,188,8,35,151,86,226,143,59,250,78,101,209,16,164,70,242,51,135,172,24,217,109,3,183,118,194,233,93,156,40,202,126,191,11,32,148,85,225,140,56,249,77,102,210,19,167,69,241,48,132,175,27,218,110,6,178,115,199,236,88,153,45,207,123,186,14,37,145,80,228,137,61,252,72,99,215,22,162,64,244,53,129,170,30,223,107,5,177,112,196,239,91,154,46,204,120,185,13,38,146,83,231,138,62,255,75,96,212,21,161,67,247,54,130,169,29,220,104,12,184,121,205,230,82,147,39,197,113,176,4,47,155,90,238,131,55,246,66,105,221,28,168,74,254,63,139,160,20,213,97,15,187,122,206,229,81,144,36,198,114,179,7,44,152,89,237,128,52,245,65,106,222,31,171,73,253,60,136,163,23,214,98,10,190,127,203,224,84,149,33,195,119,182,2,41,157,92,232,133,49,240,68,111,219,26,174,76,248,57,141,166,18,211,103,9,189,124,200,227,87,150,34,192,116,181,1,42,158,95,235,134,50,243,71,108,216,25,173,79,251,58,142,165,17,208,100,0,181,119,194,238,91,153,44,193,116,182,3,47,154,88,237,159,42,232,93,113,196,6,179,94,235,41,156,176,5,199,114,35,150,84,225,205,120,186,15,226,87,149,32,12,185,123,206,188,9,203,126,82,231,37,144,125,200,10,191,147,38,228,81,70,243,49,132,168,29,223,106,135,50,240,69,105,220,30,171,217,108,174,27,55,130,64,245,24,173,111,218,246,67,129,52,101,208,18,167,139,62,252,73,164,17,211,102,74,255,61,136,250,79,141,56,20,161,99,214,59,142,76,249,213,96,162,23,140,57,251,78,98,215,21,160,77,248,58,143,163,22,212,97,19,166,100,209,253,72,138,63,210,103,165,16,60,137,75,254,175,26,216,109,65,244,54,131,110,219,25,172,128,53,247,66,48,133,71,242,222,107,169,28,241,68,134,51,31,170,104,221,202,127,189,8,36,145,83,230,11,190,124,201,229,80,146,39,85,224,34,151,187,14,204,121,148,33,227,86,122,207,13,184,233,92,158,43,7,178,112,197,40,157,95,234,198,115,177,4,118,195,1,180,152,45,239,90,183,2,192,117,89,236,46,155,0,182,113,199,226,84,147,37,217,111,168,30,59,141,74,252,175,25,222,104,77,251,60,138,118,192,7,177,148,34,229,83,67,245,50,132,161,23,208,102,154,44,235,93,120,206,9,191,236,90,157,43,14,184,127,201,53,131,68,242,215,97,166,16,134,48,247,65,100,210,21,163,95,233,46,152,189,11,204,122,41,159,88,238,203,125,186,12,240,70,129,55,18,164,99,213,197,115,180,2,39,145,86,224,28,170,109,219,254,72,143,57,106,220,27,173,136,62,249,79,179,5,194,116,81,231,32,150,17,167,96,214,243,69,130,52,200,126,185,15,42,156,91,237,190,8,207,121,92,234,45,155,103,209,22,160,133,51,244,66,82,228,35,149,176,6,193,119,139,61,250,76,105,223,24,174,253,75,140,58,31,169,110,216,36,146,85,227,198,112,183,1,151,33,230,80,117,195,4,178,78,248,63,137,172,26,221,107,56,142,73,255,218,108,171,29,225,87,144,38,3,181,114,196,212,98,165,19,54,128,71,241,13,187,124,202,239,89,158,40,123,205,10,188,153,47,232,94,162,20,211,101,64,246,49,135,0,183,115,196,230,81,149,34,209,102,162,21,55,128,68,243,191,8,204,123,89,238,42,157,110,217,29,170,136,63,251,76,99,212,16,167,133,50,246,65,178,5,193,118,84,227,39,144,220,107,175,24,58,141,73,254,13,186,126,201,235,92,152,47,198,113,181,2,32,151,83,228,23,160,100,211,241,70,130,53,121,206,10,189,159,40,236,91,168,31,219,108,78,249,61,138,165,18,214,97,67,244,48,135,116,195,7,176,146,37,225,86,26,173,105,222,252,75,143,56,203,124,184,15,45,154,94,233,145,38,226,85,119,192,4,179,64,247,51,132,166,17,213,98,46,153,93,234,200,127,187,12,255,72,140,59,25,174,106,221,242,69,129,54,20,163,103,208,35,148,80,231,197,114,182,1,77,250,62,137,171,28,216,111,156,43,239,88,122,205,9,190,87,224,36,147,177,6,194,117,134,49,245,66,96,215,19,164,232,95,155,44,14,185,125,202,57,142,74,253,223,104,172,27,52,131,71,240,210,101,161,22,229,82,150,33,3,180,112,199,139,60,248,79,109,218,30,169,90,237,41,158,188,11,207,120,0,184,109,213,218,98,183,15,169,17,196,124,115,203,30,166,79,247,34,154,149,45,248,64,230,94,139,51,60,132,81,233,158,38,243,75,68,252,41,145,55,143,90,226,237,85,128,56,209,105,188,4,11,179,102,222,120,192,21,173,162,26,207,119,33,153,76,244,251,67,150,46,136,48,229,93,82,234,63,135,110,214,3,187,180,12,217,97,199,127,170,18,29,165,112,200,191,7,210,106,101,221,8,176,22,174,123,195,204,116,161,25,240,72,157,37,42,146,71,255,89,225,52,140,131,59,238,86,66,250,47,151,152,32,245,77,235,83,134,62,49,137,92,228,13,181,96,216,215,111,186,2,164,28,201,113,126,198,19,171,220,100,177,9,6,190,107,211,117,205,24,160,175,23,194,122,147,43,254,70,73,241,36,156,58,130,87,239,224,88,141,53,99,219,14,182,185,1,212,108,202,114,167,31,16,168,125,197,44,148,65,249,246,78,155,35,133,61,232,80,95,231,50,138,253,69,144,40,39,159,74,242,84,236,57,129,142,54,227,91,178,10,223,103,104,208,5,189,27,163,118,206,193,121,172,20,0,185,111,214,222,103,177,8,161,24,206,119,127,198,16,169,95,230,48,137,129,56,238,87,254,71,145,40,32,153,79,246,190,7,209,104,96,217,15,182,31,166,112,201,193,120,174,23,225,88,142,55,63,134,80,233,64,249,47,150,158,39,241,72,97,216,14,183,191,6,208,105,192,121,175,22,30,167,113,200,62,135,81,232,224,89,143,54,159,38,240,73,65,248,46,151,223,102,176,9,1,184,110,215,126,199,17,168,160,25,207,118,128,57,239,86,94,231,49,136,33,152,78,247,255,70,144,41,194,123,173,20,28,165,115,202,99,218,12,181,189,4,210,107,157,36,242,75,67,250,44,149,60,133,83,234,226,91,141,52,124,197,19,170,162,27,205,116,221,100,178,11,3,186,108,213,35,154,76,245,253,68,146,43,130,59,237,84,92,229,51,138,163,26,204,117,125,196,18,171,2,187,109,212,220,101,179,10,252,69,147,42,34,155,77,244,93,228,50,139,131,58,236,85,29,164,114,203,195,122,172,21,188,5,211,106,98,219,13,180,66,251,45,148,156,37,243,74,227,90,140,53,61,132,82,235,0,186,105,211,210,104,187,1,185,3,208,106,107,209,2,184,111,213,6,188,189,7,212,110,214,108,191,5,4,190,109,215,222,100,183,13,12,182,101,223,103,221,14,180,181,15,220,102,177,11,216,98,99,217,10,176,8,178,97,219,218,96,179,9,161,27,200,114,115,201,26,160,24,162,113,203,202,112,163,25,206,116,167,29,28,166,117,207,119,205,30,164,165,31,204,118,127,197,22,172,173,23,196,126,198,124,175,21,20,174,125,199,16,170,121,195,194,120,171,17,169,19,192,122,123,193,18,168,95,229,54,140,141,55,228,94,230,92,143,53,52,142,93,231,48,138,89,227,226,88,139,49,137,51,224,90,91,225,50,136,129,59,232,82,83,233,58,128,56,130,81,235,234,80,131,57,238,84,135,61,60,134,85,239,87,237,62,132,133,63,236,86,254,68,151,45,44,150,69,255,71,253,46,148,149,47,252,70,145,43,248,66,67,249,42,144,40,146,65,251,250,64,147,41,32,154,73,243,242,72,155,33,153,35,240,74,75,241,34,152,79,245,38,156,157,39,244,78,246,76,159,37,36,158,77,247,0,187,107,208,214,109,189,6,177,10,218,97,103,220,12,183,127,196,20,175,169,18,194,121,206,117,165,30,24,163,115,200,254,69,149,46,40,147,67,248,79,244,36,159,153,34,242,73,129,58,234,81,87,236,60,135,48,139,91,224,230,93,141,54,225,90,138,49,55,140,92,231,80,235,59,128,134,61,237,86,158,37,245,78,72,243,35,152,47,148,68,255,249,66,146,41,31,164,116,207,201,114,162,25,174,21,197,126,120,195,19,168,96,219,11,176,182,13,221,102,209,106,186,1,7,188,108,215,223,100,180,15,9,178,98,217,110,213,5,190,184,3,211,104,160,27,203,112,118,205,29,166,17,170,122,193,199,124,172,23,33,154,74,241,247,76,156,39,144,43,251,64,70,253,45,150,94,229,53,142,136,51,227,88,239,84,132,63,57,130,82,233,62,133,85,238,232,83,131,56,143,52,228,95,89,226,50,137,65,250,42,145,151,44,252,71,240,75,155,32,38,157,77,246,192,123,171,16,22,173,125,198,113,202,26,161,167,28,204,119,191,4,212,111,105,210,2,185,14,181,101,222,216,99,179,8,0,188,101,217,202,118,175,19,137,53,236,80,67,255,38,154,15,179,106,214,197,121,160,28,134,58,227,95,76,240,41,149,30,162,123,199,212,104,177,13,151,43,242,78,93,225,56,132,17,173,116,200,219,103,190,2,152,36,253,65,82,238,55,139,60,128,89,229,246,74,147,47,181,9,208,108,127,195,26,166,51,143,86,234,249,69,156,32,186,6,223,99,112,204,21,169,34,158,71,251,232,84,141,49,171,23,206,114,97,221,4,184,45,145,72,244,231,91,130,62,164,24,193,125,110,210,11,183,120,196,29,161,178,14,215,107,241,77,148,40,59,135,94,226,119,203,18,174,189,1,216,100,254,66,155,39,52,136,81,237,102,218,3,191,172,16,201,117,239,83,138,54,37,153,64,252,105,213,12,176,163,31,198,122,224,92,133,57,42,150,79,243,68,248,33,157,142,50,235,87,205,113,168,20,7,187,98,222,75,247,46,146,129,61,228,88,194,126,167,27,8,180,109,209,90,230,63,131,144,44,245,73,211,111,182,10,25,165,124,192,85,233,48,140,159,35,250,70,220,96,185,5,22,170,115,207,0,189,103,218,206,115,169,20,129,60,230,91,79,242,40,149,31,162,120,197,209,108,182,11,158,35,249,68,80,237,55,138,62,131,89,228,240,77,151,42,191,2,216,101,113,204,22,171,33,156,70,251,239,82,136,53,160,29,199,122,110,211,9,180,124,193,27,166,178,15,213,104,253,64,154,39,51,142,84,233,99,222,4,185,173,16,202,119,226,95,133,56,44,145,75,246,66,255,37,152,140,49,235,86,195,126,164,25,13,176,106,215,93,224,58,135,147,46,244,73,220,97,187,6,18,175,117,200,248,69,159,34,54,139,81,236,121,196,30,163,183,10,208,109,231,90,128,61,41,148,78,243,102,219,1,188,168,21,207,114,198,123,161,28,8,181,111,210,71,250,32,157,137,52,238,83,217,100,190,3,23,170,112,205,88,229,63,130,150,43,241,76,132,57,227,94,74,247,45,144,5,184,98,223,203,118,172,17,155,38,252,65,85,232,50,143,26,167,125,192,212,105,179,14,186,7,221,96,116,201,19,174,59,134,92,225,245,72,146,47,165,24,194,127,107,214,12,177,36,153,67,254,234,87,141,48,0,190,97,223,194,124,163,29,153,39,248,70,91,229,58,132,47,145,78,240,237,83,140,50,182,8,215,105,116,202,21,171,94,224,63,129,156,34,253,67,199,121,166,24,5,187,100,218,113,207,16,174,179,13,210,108,232,86,137,55,42,148,75,245,188,2,221,99,126,192,31,161,37,155,68,250,231,89,134,56,147,45,242,76,81,239,48,142,10,180,107,213,200,118,169,23,226,92,131,61,32,158,65,255,123,197,26,164,185,7,216,102,205,115,172,18,15,177,110,208,84,234,53,139,150,40,247,73,101,219,4,186,167,25,198,120,252,66,157,35,62,128,95,225,74,244,43,149,136,54,233,87,211,109,178,12,17,175,112,206,59,133,90,228,249,71,152,38,162,28,195,125,96,222,1,191,20,170,117,203,214,104,183,9,141,51,236,82,79,241,46,144,217,103,184,6,27,165,122,196,64,254,33,159,130,60,227,93,246,72,151,41,52,138,85,235,111,209,14,176,173,19,204,114,135,57,230,88,69,251,36,154,30,160,127,193,220,98,189,3,168,22,201,119,106,212,11,181,49,143,80,238,243,77,146,44,0,191,99,220,198,121,165,26,145,46,242,77,87,232,52,139,63,128,92,227,249,70,154,37,174,17,205,114,104,215,11,180,126,193,29,162,184,7,219,100,239,80,140,51,41,150,74,245,65,254,34,157,135,56,228,91,208,111,179,12,22,169,117,202,252,67,159,32,58,133,89,230,109,210,14,177,171,20,200,119,195,124,160,31,5,186,102,217,82,237,49,142,148,43,247,72,130,61,225,94,68,251,39,152,19,172,112,207,213,106,182,9,189,2,222,97,123,196,24,167,44,147,79,240,234,85,137,54,229,90,134,57,35,156,64,255,116,203,23,168,178,13,209,110,218,101,185,6,28,163,127,192,75,244,40,151,141,50,238,81,155,36,248,71,93,226,62,129,10,181,105,214,204,115,175,16,164,27,199,120,98,221,1,190,53,138,86,233,243,76,144,47,25,166,122,197,223,96,188,3,136,55,235,84,78,241,45,146,38,153,69,250,224,95,131,60,183,8,212,107,113,206,18,173,103,216,4,187,161,30,194,125,246,73,149,42,48,143,83,236,88,231,59,132,158,33,253,66,201,118,170,21,15,176,108,211,0,192,157,93,39,231,186,122,78,142,211,19,105,169,244,52,156,92,1,193,187,123,38,230,210,18,79,143,245,53,104,168,37,229,184,120,2,194,159,95,107,171,246,54,76,140,209,17,185,121,36,228,158,94,3,195,247,55,106,170,208,16,77,141,74,138,215,23,109,173,240,48,4,196,153,89,35,227,190,126,214,22,75,139,241,49,108,172,152,88,5,197,191,127,34,226,111,175,242,50,72,136,213,21,33,225,188,124,6,198,155,91,243,51,110,174,212,20,73,137,189,125,32,224,154,90,7,199,148,84,9,201,179,115,46,238,218,26,71,135,253,61,96,160,8,200,149,85,47,239,178,114,70,134,219,27,97,161,252,60,177,113,44,236,150,86,11,203,255,63,98,162,216,24,69,133,45,237,176,112,10,202,151,87,99,163,254,62,68,132,217,25,222,30,67,131,249,57,100,164,144,80,13,205,183,119,42,234,66,130,223,31,101,165,248,56,12,204,145,81,43,235,182,118,251,59,102,166,220,28,65,129,181,117,40,232,146,82,15,207,103,167,250,58,64,128,221,29,41,233,180,116,14,206,147,83,0,193,159,94,35,226,188,125,70,135,217,24,101,164,250,59,140,77,19,210,175,110,48,241,202,11,85,148,233,40,118,183,5,196,154,91,38,231,185,120,67,130,220,29,96,161,255,62,137,72,22,215,170,107,53,244,207,14,80,145,236,45,115,178,10,203,149,84,41,232,182,119,76,141,211,18,111,174,240,49,134,71,25,216,165,100,58,251,192,1,95,158,227,34,124,189,15,206,144,81,44,237,179,114,73,136,214,23,106,171,245,52,131,66,28,221,160,97,63,254,197,4,90,155,230,39,121,184,20,213,139,74,55,246,168,105,82,147,205,12,113,176,238,47,152,89,7,198,187,122,36,229,222,31,65,128,253,60,98,163,17,208,142,79,50,243,173,108,87,150,200,9,116,181,235,42,157,92,2,195,190,127,33,224,219,26,68,133,248,57,103,166,30,223,129,64,61,252,162,99,88,153,199,6,123,186,228,37,146,83,13,204,177,112,46,239,212,21,75,138,247,54,104,169,27,218,132,69,56,249,167,102,93,156,194,3,126,191,225,32,151,86,8,201,180,117,43,234,209,16,78,143,242,51,109,172,0,194,153,91,47,237,182,116,94,156,199,5,113,179,232,42,188,126,37,231,147,81,10,200,226,32,123,185,205,15,84,150,101,167,252,62,74,136,211,17,59,249,162,96,20,214,141,79,217,27,64,130,246,52,111,173,135,69,30,220,168,106,49,243,202,8,83,145,229,39,124,190,148,86,13,207,187,121,34,224,118,180,239,45,89,155,192,2,40,234,177,115,7,197,158,92,175,109,54,244,128,66,25,219,241,51,104,170,222,28,71,133,19,209,138,72,60,254,165,103,77,143,212,22,98,160,251,57,137,75,16,210,166,100,63,253,215,21,78,140,248,58,97,163,53,247,172,110,26,216,131,65,107,169,242,48,68,134,221,31,236,46,117,183,195,1,90,152,178,112,43,233,157,95,4,198,80,146,201,11,127,189,230,36,14,204,151,85,33,227,184,122,67,129,218,24,108,174,245,55,29,223,132,70,50,240,171,105,255,61,102,164,208,18,73,139,161,99,56,250,142,76,23,213,38,228,191,125,9,203,144,82,120,186,225,35,87,149,206,12,154,88,3,193,181,119,44,238,196,6,93,159,235,41,114,176,0,195,155,88,43,232,176,115,86,149,205,14,125,190,230,37,172,111,55,244,135,68,28,223,250,57,97,162,209,18,74,137,69,134,222,29,110,173,245,54,19,208,136,75,56,251,163,96,233,42,114,177,194,1,89,154,191,124,36,231,148,87,15,204,138,73,17,210,161,98,58,249,220,31,71,132,247,52,108,175,38,229,189,126,13,206,150,85,112,179,235,40,91,152,192,3,207,12,84,151,228,39,127,188,153,90,2,193,178,113,41,234,99,160,248,59,72,139,211,16,53,246,174,109,30,221,133,70,9,202,146,81,34,225,185,122,95,156,196,7,116,183,239,44,165,102,62,253,142,77,21,214,243,48,104,171,216,27,67,128,76,143,215,20,103,164,252,63,26,217,129,66,49,242,170,105,224,35,123,184,203,8,80,147,182,117,45,238,157,94,6,197,131,64,24,219,168,107,51,240,213,22,78,141,254,61,101,166,47,236,180,119,4,199,159,92,121,186,226,33,82,145,201,10,198,5,93,158,237,46,118,181,144,83,11,200,187,120,32,227,106,169,241,50,65,130,218,25,60,255,167,100,23,212,140,79,0,196,149,81,55,243,162,102,110,170,251,63,89,157,204,8,220,24,73,141,235,47,126,186,178,118,39,227,133,65,16,212,165,97,48,244,146,86,7,195,203,15,94,154,252,56,105,173,121,189,236,40,78,138,219,31,23,211,130,70,32,228,181,113,87,147,194,6,96,164,245,49,57,253,172,104,14,202,155,95,139,79,30,218,188,120,41,237,229,33,112,180,210,22,71,131,242,54,103,163,197,1,80,148,156,88,9,205,171,111,62,250,46,234,187,127,25,221,140,72,64,132,213,17,119,179,226,38,174,106,59,255,153,93,12,200,192,4,85,145,247,51,98,166,114,182,231,35,69,129,208,20,28,216,137,77,43,239,190,122,11,207,158,90,60,248,169,109,101,161,240,52,82,150,199,3,215,19,66,134,224,36,117,177,185,125,44,232,142,74,27,223,249,61,108,168,206,10,91,159,151,83,2,198,160,100,53,241,37,225,176,116,18,214,135,67,75,143,222,26,124,184,233,45,92,152,201,13,107,175,254,58,50,246,167,99,5,193,144,84,128,68,21,209,183,115,34,230,238,42,123,191,217,29,76,136,0,197,151,82,51,246,164,97,102,163,241,52,85,144,194,7,204,9,91,158,255,58,104,173,170,111,61,248,153,92,14,203,133,64,18,215,182,115,33,228,227,38,116,177,208,21,71,130,73,140,222,27,122,191,237,40,47,234,184,125,28,217,139,78,23,210,128,69,36,225,179,118,113,180,230,35,66,135,213,16,219,30,76,137,232,45,127,186,189,120,42,239,142,75,25,220,146,87,5,192,161,100,54,243,244,49,99,166,199,2,80,149,94,155,201,12,109,168,250,63,56,253,175,106,11,206,156,89,46,235,185,124,29,216,138,79,72,141,223,26,123,190,236,41,226,39,117,176,209,20,70,131,132,65,19,214,183,114,32,229,171,110,60,249,152,93,15,202,205,8,90,159,254,59,105,172,103,162,240,53,84,145,195,6,1,196,150,83,50,247,165,96,57,252,174,107,10,207,157,88,95,154,200,13,108,169,251,62,245,48,98,167,198,3,81,148,147,86,4,193,160,101,55,242,188,121,43,238,143,74,24,221,218,31,77,136,233,44,126,187,112,181,231,34,67,134,212,17,22,211,129,68,37,224,178,119,0,198,145,87,63,249,174,104,126,184,239,41,65,135,208,22,252,58,109,171,195,5,82,148,130,68,19,213,189,123,44,234,229,35,116,178,218,28,75,141,155,93,10,204,164,98,53,243,25,223,136,78,38,224,183,113,103,161,246,48,88,158,201,15,215,17,70,128,232,46,121,191,169,111,56,254,150,80,7,193,43,237,186,124,20,210,133,67,85,147,196,2,106,172,251,61,50,244,163,101,13,203,156,90,76,138,221,27,115,181,226,36,206,8,95,153,241,55,96,166,176,118,33,231,143,73,30,216,179,117,34,228,140,74,29,219,205,11,92,154,242,52,99,165,79,137,222,24,112,182,225,39,49,247,160,102,14,200,159,89,86,144,199,1,105,175,248,62,40,238,185,127,23,209,134,64,170,108,59,253,149,83,4,194,212,18,69,131,235,45,122,188,100,162,245,51,91,157,202,12,26,220,139,77,37,227,180,114,152,94,9,207,167,97,54,240,230,32,119,177,217,31,72,142,129,71,16,214,190,120,47,233,255,57,110,168,192,6,81,151,125,187,236,42,66,132,211,21,3,197,146,84,60,250,173,107,0,199,147,84,59,252,168,111,118,177,229,34,77,138,222,25,236,43,127,184,215,16,68,131,154,93,9,206,161,102,50,245,197,2,86,145,254,57,109,170,179,116,32,231,136,79,27,220,41,238,186,125,18,213,129,70,95,152,204,11,100,163,247,48,151,80,4,195,172,107,63,248,225,38,114,181,218,29,73,142,123,188,232,47,64,135,211,20,13,202,158,89,54,241,165,98,82,149,193,6,105,174,250,61,36,227,183,112,31,216,140,75,190,121,45,234,133,66,22,209,200,15,91,156,243,52,96,167,51,244,160,103,8,207,155,92,69,130,214,17,126,185,237,42,223,24,76,139,228,35,119,176,169,110,58,253,146,85,1,198,246,49,101,162,205,10,94,153,128,71,19,212,187,124,40,239,26,221,137,78,33,230,178,117,108,171,255,56,87,144,196,3,164,99,55,240,159,88,12,203,210,21,65,134,233,46,122,189,72,143,219,28,115,180,224,39,62,249,173,106,5,194,150,81,97,166,242,53,90,157,201,14,23,208,132,67,44,235,191,120,141,74,30,217,182,113,37,226,251,60,104,175,192,7,83,148,0,200,141,69,7,207,138,66,14,198,131,75,9,193,132,76,28,212,145,89,27,211,150,94,18,218,159,87,21,221,152,80,56,240,181,125,63,247,178,122,54,254,187,115,49,249,188,116,36,236,169,97,35,235,174,102,42,226,167,111,45,229,160,104,112,184,253,53,119,191,250,50,126,182,243,59,121,177,244,60,108,164,225,41,107,163,230,46,98,170,239,39,101,173,232,32,72,128,197,13,79,135,194,10,70,142,203,3,65,137,204,4,84,156,217,17,83,155,222,22,90,146,215,31,93,149,208,24,224,40,109,165,231,47,106,162,238,38,99,171,233,33,100,172,252,52,113,185,251,51,118,190,242,58,127,183,245,61,120,176,216,16,85,157,223,23,82,154,214,30,91,147,209,25,92,148,196,12,73,129,195,11,78,134,202,2,71,143,205,5,64,136,144,88,29,213,151,95,26,210,158,86,19,219,153,81,20,220,140,68,1,201,139,67,6,206,130,74,15,199,133,77,8,192,168,96,37,237,175,103,34,234,166,110,43,227,161,105,44,228,180,124,57,241,179,123,62,246,186,114,55,255,189,117,48,248,0,201,143,70,3,202,140,69,6,207,137,64,5,204,138,67,12,197,131,74,15,198,128,73,10,195,133,76,9,192,134,79,24,209,151,94,27,210,148,93,30,215,145,88,29,212,146,91,20,221,155,82,23,222,152,81,18,219,157,84,17,216,158,87,48,249,191,118,51,250,188,117,54,255,185,112,53,252,186,115,60,245,179,122,63,246,176,121,58,243,181,124,57,240,182,127,40,225,167,110,43,226,164,109,46,231,161,104,45,228,162,107,36,237,171,98,39,238,168,97,34,235,173,100,33,232,174,103,96,169,239,38,99,170,236,37,102,175,233,32,101,172,234,35,108,165,227,42,111,166,224,41,106,163,229,44,105,160,230,47,120,177,247,62,123,178,244,61,126,183,241,56,125,180,242,59,116,189,251,50,119,190,248,49,114,187,253,52,113,184,254,55,80,153,223,22,83,154,220,21,86,159,217,16,85,156,218,19,92,149,211,26,95,150,208,25,90,147,213,28,89,144,214,31,72,129,199,14,75,130,196,13,78,135,193,8,77,132,194,11,68,141,203,2,71,142,200,1,66,139,205,4,65,136,206,7,0,202,137,67,15,197,134,76,30,212,151,93,17,219,152,82,60,246,181,127,51,249,186,112,34,232,171,97,45,231,164,110,120,178,241,59,119,189,254,52,102,172,239,37,105,163,224,42,68,142,205,7,75,129,194,8,90,144,211,25,85,159,220,22,240,58,121,179,255,53,118,188,238,36,103,173,225,43,104,162,204,6,69,143,195,9,74,128,210,24,91,145,221,23,84,158,136,66,1,203,135,77,14,196,150,92,31,213,153,83,16,218,180,126,61,247,187,113,50,248,170,96,35,233,165,111,44,230,253,55,116,190,242,56,123,177,227,41,106,160,236,38,101,175,193,11,72,130,206,4,71,141,223,21,86,156,208,26,89,147,133,79,12,198,138,64,3,201,155,81,18,216,148,94,29,215,185,115,48,250,182,124,63,245,167,109,46,228,168,98,33,235,13,199,132,78,2,200,139,65,19,217,154,80,28,214,149,95,49,251,184,114,62,244,183,125,47,229,166,108,32,234,169,99,117,191,252,54,122,176,243,57,107,161,226,40,100,174,237,39,73,131,192,10,70,140,207,5,87,157,222,20,88,146,209,27,0,203,139,64,11,192,128,75,22,221,157,86,29,214,150,93,44,231,167,108,39,236,172,103,58,241,177,122,49,250,186,113,88,147,211,24,83,152,216,19,78,133,197,14,69,142,206,5,116,191,255,52,127,180,244,63,98,169,233,34,105,162,226,41,176,123,59,240,187,112,48,251,166,109,45,230,173,102,38,237,156,87,23,220,151,92,28,215,138,65,1,202,129,74,10,193,232,35,99,168,227,40,104,163,254,53,117,190,245,62,126,181,196,15,79,132,207,4,68,143,210,25,89,146,217,18,82,153,125,182,246,61,118,189,253,54,107,160,224,43,96,171,235,32,81,154,218,17,90,145,209,26,71,140,204,7,76,135,199,12,37,238,174,101,46,229,165,110,51,248,184,115,56,243,179,120,9,194,130,73,2,201,137,66,31,212,148,95,20,223,159,84,205,6,70,141,198,13,77,134,219,16,80,155,208,27,91,144,225,42,106,161,234,33,97,170,247,60,124,183,252,55,119,188,149,94,30,213,158,85,21,222,131,72,8,195,136,67,3,200,185,114,50,249,178,121,57,242,175,100,36,239,164,111,47,228,0,204,133,73,23,219,146,94,46,226,171,103,57,245,188,112,92,144,217,21,75,135,206,2,114,190,247,59,101,169,224,44,184,116,61,241,175,99,42,230,150,90,19,223,129,77,4,200,228,40,97,173,243,63,118,186,202,6,79,131,221,17,88,148,109,161,232,36,122,182,255,51,67,143,198,10,84,152,209,29,49,253,180,120,38,234,163,111,31,211,154,86,8,196,141,65,213,25,80,156,194,14,71,139,251,55,126,178,236,32,105,165,137,69,12,192,158,82,27,215,167,107,34,238,176,124,53,249,218,22,95,147,205,1,72,132,244,56,113,189,227,47,102,170,134,74,3,207,145,93,20,216,168,100,45,225,191,115,58,246,98,174,231,43,117,185,240,60,76,128,201,5,91,151,222,18,62,242,187,119,41,229,172,96,16,220,149,89,7,203,130,78,183,123,50,254,160,108,37,233,153,85,28,208,142,66,11,199,235,39,110,162,252,48,121,181,197,9,64,140,210,30,87,155,15,195,138,70,24,212,157,81,33,237,164,104,54,250,179,127,83,159,214,26,68,136,193,13,125,177,248,52,106,166,239,35,0,205,135,74,19,222,148,89,38,235,161,108,53,248,178,127,76,129,203,6,95,146,216,21,106,167,237,32,121,180,254,51,152,85,31,210,139,70,12,193,190,115,57,244,173,96,42,231,212,25,83,158,199,10,64,141,242,63,117,184,225,44,102,171,45,224,170,103,62,243,185,116,11,198,140,65,24,213,159,82,97,172,230,43,114,191,245,56,71,138,192,13,84,153,211,30,181,120,50,255,166,107,33,236,147,94,20,217,128,77,7,202,249,52,126,179,234,39,109,160,223,18,88,149,204,1,75,134,90,151,221,16,73,132,206,3,124,177,251,54,111,162,232,37,22,219,145,92,5,200,130,79,48,253,183,122,35,238,164,105,194,15,69,136,209,28,86,155,228,41,99,174,247,58,112,189,142,67,9,196,157,80,26,215,168,101,47,226,187,118,60,241,119,186,240,61,100,169,227,46,81,156,214,27,66,143,197,8,59,246,188,113,40,229,175,98,29,208,154,87,14,195,137,68,239,34,104,165,252,49,123,182,201,4,78,131,218,23,93,144,163,110,36,233,176,125,55,250,133,72,2,207,150,91,17,220,0,206,129,79,31,209,158,80,62,240,191,113,33,239,160,110,124,178,253,51,99,173,226,44,66,140,195,13,93,147,220,18,248,54,121,183,231,41,102,168,198,8,71,137,217,23,88,150,132,74,5,203,155,85,26,212,186,116,59,245,165,107,36,234,237,35,108,162,242,60,115,189,211,29,82,156,204,2,77,131,145,95,16,222,142,64,15,193,175,97,46,224,176,126,49,255,21,219,148,90,10,196,139,69,43,229,170,100,52,250,181,123,105,167,232,38,118,184,247,57,87,153,214,24,72,134,201,7,199,9,70,136,216,22,89,151,249,55,120,182,230,40,103,169,187,117,58,244,164,106,37,235,133,75,4,202,154,84,27,213,63,241,190,112,32,238,161,111,1,207,128,78,30,208,159,81,67,141,194,12,92,146,221,19,125,179,252,50,98,172,227,45,42,228,171,101,53,251,180,122,20,218,149,91,11,197,138,68,86,152,215,25,73,135,200,6,104,166,233,39,119,185,246,56,210,28,83,157,205,3,76,130,236,34,109,163,243,61,114,188,174,96,47,225,177,127,48,254,144,94,17,223,143,65,14,192,0,207,131,76,27,212,152,87,54,249,181,122,45,226,174,97,108,163,239,32,119,184,244,59,90,149,217,22,65,142,194,13,216,23,91,148,195,12,64,143,238,33,109,162,245,58,118,185,180,123,55,248,175,96,44,227,130,77,1,206,153,86,26,213,173,98,46,225,182,121,53,250,155,84,24,215,128,79,3,204,193,14,66,141,218,21,89,150,247,56,116,187,236,35,111,160,117,186,246,57,110,161,237,34,67,140,192,15,88,151,219,20,25,214,154,85,2,205,129,78,47,224,172,99,52,251,183,120,71,136,196,11,92,147,223,16,113,190,242,61,106,165,233,38,43,228,168,103,48,255,179,124,29,210,158,81,6,201,133,74,159,80,28,211,132,75,7,200,169,102,42,229,178,125,49,254,243,60,112,191,232,39,107,164,197,10,70,137,222,17,93,146,234,37,105,166,241,62,114,189,220,19,95,144,199,8,68,139,134,73,5,202,157,82,30,209,176,127,51,252,171,100,40,231,50,253,177,126,41,230,170,101,4,203,135,72,31,208,156,83,94,145,221,18,69,138,198,9,104,167,235,36,115,188,240,63,0,208,189,109,103,183,218,10,206,30,115,163,169,121,20,196,129,81,60,236,230,54,91,139,79,159,242,34,40,248,149,69,31,207,162,114,120,168,197,21,209,1,108,188,182,102,11,219,158,78,35,243,249,41,68,148,80,128,237,61,55,231,138,90,62,238,131,83,89,137,228,52,240,32,77,157,151,71,42,250,191,111,2,210,216,8,101,181,113,161,204,28,22,198,171,123,33,241,156,76,70,150,251,43,239,63,82,130,136,88,53,229,160,112,29,205,199,23,122,170,110,190,211,3,9,217,180,100,124,172,193,17,27,203,166,118,178,98,15,223,213,5,104,184,253,45,64,144,154,74,39,247,51,227,142,94,84,132,233,57,99,179,222,14,4,212,185,105,173,125,16,192,202,26,119,167,226,50,95,143,133,85,56,232,44,252,145,65,75,155,246,38,66,146,255,47,37,245,152,72,140,92,49,225,235,59,86,134,195,19,126,174,164,116,25,201,13,221,176,96,106,186,215,7,93,141,224,48,58,234,135,87,147,67,46,254,244,36,73,153,220,12,97,177,187,107,6,214,18,194,175,127,117,165,200,24,0,209,191,110,99,178,220,13,198,23,121,168,165,116,26,203,145,64,46,255,242,35,77,156,87,134,232,57,52,229,139,90,63,238,128,81,92,141,227,50,249,40,70,151,154,75,37,244,174,127,17,192,205,28,114,163,104,185,215,6,11,218,180,101,126,175,193,16,29,204,162,115,184,105,7,214,219,10,100,181,239,62,80,129,140,93,51,226,41,248,150,71,74,155,245,36,65,144,254,47,34,243,157,76,135,86,56,233,228,53,91,138,208,1,111,190,179,98,12,221,22,199,169,120,117,164,202,27,252,45,67,146,159,78,32,241,58,235,133,84,89,136,230,55,109,188,210,3,14,223,177,96,171,122,20,197,200,25,119,166,195,18,124,173,160,113,31,206,5,212,186,107,102,183,217,8,82,131,237,60,49,224,142,95,148,69,43,250,247,38,72,153,130,83,61,236,225,48,94,143,68,149,251,42,39,246,152,73,19,194,172,125,112,161,207,30,213,4,106,187,182,103,9,216,189,108,2,211,222,15,97,176,123,170,196,21,24,201,167,118,44,253,147,66,79,158,240,33,234,59,85,132,137,88,54,231,0,210,185,107,111,189,214,4,222,12,103,181,177,99,8,218,161,115,24,202,206,28,119,165,127,173,198,20,16,194,169,123,95,141,230,52,48,226,137,91,129,83,56,234,238,60,87,133,254,44,71,149,145,67,40,250,32,242,153,75,79,157,246,36,190,108,7,213,209,3,104,186,96,178,217,11,15,221,182,100,31,205,166,116,112,162,201,27,193,19,120,170,174,124,23,197,225,51,88,138,142,92,55,229,63,237,134,84,80,130,233,59,64,146,249,43,47,253,150,68,158,76,39,245,241,35,72,154,97,179,216,10,14,220,183,101,191,109,6,212,208,2,105,187,192,18,121,171,175,125,22,196,30,204,167,117,113,163,200,26,62,236,135,85,81,131,232,58,224,50,89,139,143,93,54,228,159,77,38,244,240,34,73,155,65,147,248,42,46,252,151,69,223,13,102,180,176,98,9,219,1,211,184,106,110,188,215,5,126,172,199,21,17,195,168,122,160,114,25,203,207,29,118,164,128,82,57,235,239,61,86,132,94,140,231,53,49,227,136,90,33,243,152,74,78,156,247,37,255,45,70,148,144,66,41,251,0,211,187,104,107,184,208,3,214,5,109,190,189,110,6,213,177,98,10,217,218,9,97,178,103,180,220,15,12,223,183,100,127,172,196,23,20,199,175,124,169,122,18,193,194,17,121,170,206,29,117,166,165,118,30,205,24,203,163,112,115,160,200,27,254,45,69,150,149,70,46,253,40,251,147,64,67,144,248,43,79,156,244,39,36,247,159,76,153,74,34,241,242,33,73,154,129,82,58,233,234,57,81,130,87,132,236,63,60,239,135,84,48,227,139,88,91,136,224,51,230,53,93,142,141,94,54,229,225,50,90,137,138,89,49,226,55,228,140,95,92,143,231,52,80,131,235,56,59,232,128,83,134,85,61,238,237,62,86,133,158,77,37,246,245,38,78,157,72,155,243,32,35,240,152,75,47,252,148,71,68,151,255,44,249,42,66,145,146,65,41,250,31,204,164,119,116,167,207,28,201,26,114,161,162,113,25,202,174,125,21,198,197,22,126,173,120,171,195,16,19,192,168,123,96,179,219,8,11,216,176,99,182,101,13,222,221,14,102,181,209,2,106,185,186,105,1,210,7,212,188,111,108,191,215,4,0,212,181,97,119,163,194,22,238,58,91,143,153,77,44,248,193,21,116,160,182,98,3,215,47,251,154,78,88,140,237,57,159,75,42,254,232,60,93,137,113,165,196,16,6,210,179,103,94,138,235,63,41,253,156,72,176,100,5,209,199,19,114,166,35,247,150,66,84,128,225,53,205,25,120,172,186,110,15,219,226,54,87,131,149,65,32,244,12,216,185,109,123,175,206,26,188,104,9,221,203,31,126,170,82,134,231,51,37,241,144,68,125,169,200,28,10,222,191,107,147,71,38,242,228,48,81,133,70,146,243,39,49,229,132,80,168,124,29,201,223,11,106,190,135,83,50,230,240,36,69,145,105,189,220,8,30,202,171,127,217,13,108,184,174,122,27,207,55,227,130,86,64,148,245,33,24,204,173,121,111,187,218,14,246,34,67,151,129,85,52,224,101,177,208,4,18,198,167,115,139,95,62,234,252,40,73,157,164,112,17,197,211,7,102,178,74,158,255,43,61,233,136,92,250,46,79,155,141,89,56,236,20,192,161,117,99,183,214,2,59,239,142,90,76,152,249,45,213,1,96,180,162,118,23,195,0,213,183,98,115,166,196,17,230,51,81,132,149,64,34,247,209,4,102,179,162,119,21,192,55,226,128,85,68,145,243,38,191,106,8,221,204,25,123,174,89,140,238,59,42,255,157,72,110,187,217,12,29,200,170,127,136,93,63,234,251,46,76,153,99,182,212,1,16,197,167,114,133,80,50,231,246,35,65,148,178,103,5,208,193,20,118,163,84,129,227,54,39,242,144,69,220,9,107,190,175,122,24,205,58,239,141,88,73,156,254,43,13,216,186,111,126,171,201,28,235,62,92,137,152,77,47,250,198,19,113,164,181,96,2,215,32,245,151,66,83,134,228,49,23,194,160,117,100,177,211,6,241,36,70,147,130,87,53,224,121,172,206,27,10,223,189,104,159,74,40,253,236,57,91,142,168,125,31,202,219,14,108,185,78,155,249,44,61,232,138,95,165,112,18,199,214,3,97,180,67,150,244,33,48,229,135,82,116,161,195,22,7,210,176,101,146,71,37,240,225,52,86,131,26,207,173,120,105,188,222,11,252,41,75,158,143,90,56,237,203,30,124,169,184,109,15,218,45,248,154,79,94,139,233,60,0,214,177,103,127,169,206,24,254,40,79,153,129,87,48,230,225,55,80,134,158,72,47,249,31,201,174,120,96,182,209,7,223,9,110,184,160,118,17,199,33,247,144,70,94,136,239,57,62,232,143,89,65,151,240,38,192,22,113,167,191,105,14,216,163,117,18,196,220,10,109,187,93,139,236,58,34,244,147,69,66,148,243,37,61,235,140,90,188,106,13,219,195,21,114,164,124,170,205,27,3,213,178,100,130,84,51,229,253,43,76,154,157,75,44,250,226,52,83,133,99,181,210,4,28,202,173,123,91,141,234,60,36,242,149,67,165,115,20,194,218,12,107,189,186,108,11,221,197,19,116,162,68,146,245,35,59,237,138,92,132,82,53,227,251,45,74,156,122,172,203,29,5,211,180,98,101,179,212,2,26,204,171,125,155,77,42,252,228,50,85,131,248,46,73,159,135,81,54,224,6,208,183,97,121,175,200,30,25,207,168,126,102,176,215,1,231,49,86,128,152,78,41,255,39,241,150,64,88,142,233,63,217,15,104,190,166,112,23,193,198,16,119,161,185,111,8,222,56,238,137,95,71,145,246,32,0,215,179,100,123,172,200,31,246,33,69,146,141,90,62,233,241,38,66,149,138,93,57,238,7,208,180,99,124,171,207,24,255,40,76,155,132,83,55,224,9,222,186,109,114,165,193,22,14,217,189,106,117,162,198,17,248,47,75,156,131,84,48,231,227,52,80,135,152,79,43,252,21,194,166,113,110,185,221,10,18,197,161,118,105,190,218,13,228,51,87,128,159,72,44,251,28,203,175,120,103,176,212,3,234,61,89,142,145,70,34,245,237,58,94,137,150,65,37,242,27,204,168,127,96,183,211,4,219,12,104,191,160,119,19,196,45,250,158,73,86,129,229,50,42,253,153,78,81,134,226,53,220,11,111,184,167,112,20,195,36,243,151,64,95,136,236,59,210,5,97,182,169,126,26,205,213,2,102,177,174,121,29,202,35,244,144,71,88,143,235,60,56,239,139,92,67,148,240,39,206,25,125,170,181,98,6,209,201,30,122,173,178,101,1,214,63,232,140,91,68,147,247,32,199,16,116,163,188,107,15,216,49,230,130,85,74,157,249,46,54,225,133,82,77,154,254,41,192,23,115,164,187,108,8,223,0,216,173,117,71,159,234,50,142,86,35,251,201,17,100,188,1,217,172,116,70,158,235,51,143,87,34,250,200,16,101,189,2,218,175,119,69,157,232,48,140,84,33,249,203,19,102,190,3,219,174,118,68,156,233,49,141,85,32,248,202,18,103,191,4,220,169,113,67,155,238,54,138,82,39,255,205,21,96,184,5,221,168,112,66,154,239,55,139,83,38,254,204,20,97,185,6,222,171,115,65,153,236,52,136,80,37,253,207,23,98,186,7,223,170,114,64,152,237,53,137,81,36,252,206,22,99,187,8,208,165,125,79,151,226,58,134,94,43,243,193,25,108,180,9,209,164,124,78,150,227,59,135,95,42,242,192,24,109,181,10,210,167,127,77,149,224,56,132,92,41,241,195,27,110,182,11,211,166,126,76,148,225,57,133,93,40,240,194,26,111,183,12,212,161,121,75,147,230,62,130,90,47,247,197,29,104,176,13,213,160,120,74,146,231,63,131,91,46,246,196,28,105,177,14,214,163,123,73,145,228,60,128,88,45,245,199,31,106,178,15,215,162,122,72,144,229,61,129,89,44,244,198,30,107,179,0,217,175,118,67,154,236,53,134,95,41,240,197,28,106,179,17,200,190,103,82,139,253,36,151,78,56,225,212,13,123,162,34,251,141,84,97,184,206,23,164,125,11,210,231,62,72,145,51,234,156,69,112,169,223,6,181,108,26,195,246,47,89,128,68,157,235,50,7,222,168,113,194,27,109,180,129,88,46,247,85,140,250,35,22,207,185,96,211,10,124,165,144,73,63,230,102,191,201,16,37,252,138,83,224,57,79,150,163,122,12,213,119,174,216,1,52,237,155,66,241,40,94,135,178,107,29,196,136,81,39,254,203,18,100,189,14,215,161,120,77,148,226,59,153,64,54,239,218,3,117,172,31,198,176,105,92,133,243,42,170,115,5,220,233,48,70,159,44,245,131,90,111,182,192,25,187,98,20,205,248,33,87,142,61,228,146,75,126,167,209,8,204,21,99,186,143,86,32,249,74,147,229,60,9,208,166,127,221,4,114,171,158,71,49,232,91,130,244,45,24,193,183,110,238,55,65,152,173,116,2,219,104,177,199,30,43,242,132,93,255,38,80,137,188,101,19,202,121,160,214,15,58,227,149,76,0,218,169,115,79,149,230,60,158,68,55,237,209,11,120,162,33,251,136,82,110,180,199,29,191,101,22,204,240,42,89,131,66,152,235,49,13,215,164,126,220,6,117,175,147,73,58,224,99,185,202,16,44,246,133,95,253,39,84,142,178,104,27,193,132,94,45,247,203,17,98,184,26,192,179,105,85,143,252,38,165,127,12,214,234,48,67,153,59,225,146,72,116,174,221,7,198,28,111,181,137,83,32,250,88,130,241,43,23,205,190,100,231,61,78,148,168,114,1,219,121,163,208,10,54,236,159,69,21,207,188,102,90,128,243,41,139,81,34,248,196,30,109,183,52,238,157,71,123,161,210,8,170,112,3,217,229,63,76,150,87,141,254,36,24,194,177,107,201,19,96,186,134,92,47,245,118,172,223,5,57,227,144,74,232,50,65,155,167,125,14,212,145,75,56,226,222,4,119,173,15,213,166,124,64,154,233,51,176,106,25,195,255,37,86,140,46,244,135,93,97,187,200,18,211,9,122,160,156,70,53,239,77,151,228,62,2,216,171,113,242,40,91,129,189,103,20,206,108,182,197,31,35,249,138,80,0,219,171,112,75,144,224,59,150,77,61,230,221,6,118,173,49,234,154,65,122,161,209,10,167,124,12,215,236,55,71,156,98,185,201,18,41,242,130,89,244,47,95,132,191,100,20,207,83,136,248,35,24,195,179,104,197,30,110,181,142,85,37,254,196,31,111,180,143,84,36,255,82,137,249,34,25,194,178,105,245,46,94,133,190,101,21,206,99,184,200,19,40,243,131,88,166,125,13,214,237,54,70,157,48,235,155,64,123,160,208,11,151,76,60,231,220,7,119,172,1,218,170,113,74,145,225,58,149,78,62,229,222,5,117,174,3,216,168,115,72,147,227,56,164,127,15,212,239,52,68,159,50,233,153,66,121,162,210,9,247,44,92,135,188,103,23,204,97,186,202,17,42,241,129,90,198,29,109,182,141,86,38,253,80,139,251,32,27,192,176,107,81,138,250,33,26,193,177,106,199,28,108,183,140,87,39,252,96,187,203,16,43,240,128,91,246,45,93,134,189,102,22,205,51,232,152,67,120,163,211,8,165,126,14,213,238,53,69,158,2,217,169,114,73,146,226,57,148,79,63,228,223,4,116,175,0,220,165,121,87,139,242,46,174,114,11,215,249,37,92,128,65,157,228,56,22,202,179,111,239,51,74,150,184,100,29,193,130,94,39,251,213,9,112,172,44,240,137,85,123,167,222,2,195,31,102,186,148,72,49,237,109,177,200,20,58,230,159,67,25,197,188,96,78,146,235,55,183,107,18,206,224,60,69,153,88,132,253,33,15,211,170,118,246,42,83,143,161,125,4,216,155,71,62,226,204,16,105,181,53,233,144,76,98,190,199,27,218,6,127,163,141,81,40,244,116,168,209,13,35,255,134,90,50,238,151,75,101,185,192,28,156,64,57,229,203,23,110,178,115,175,214,10,36,248,129,93,221,1,120,164,138,86,47,243,176,108,21,201,231,59,66,158,30,194,187,103,73,149,236,48,241,45,84,136,166,122,3,223,95,131,250,38,8,212,173,113,43,247,142,82,124,160,217,5,133,89,32,252,210,14,119,171,106,182,207,19,61,225,152,68,196,24,97,189,147,79,54,234,169,117,12,208,254,34,91,135,7,219,162,126,80,140,245,41,232,52,77,145,191,99,26,198,70,154,227,63,17,205,180,104,0,221,167,122,83,142,244,41,166,123,1,220,245,40,82,143,81,140,246,43,2,223,165,120,247,42,80,141,164,121,3,222,162,127,5,216,241,44,86,139,4,217,163,126,87,138,240,45,243,46,84,137,160,125,7,218,85,136,242,47,6,219,161,124,89,132,254,35,10,215,173,112,255,34,88,133,172,113,11,214,8,213,175,114,91,134,252,33,174,115,9,212,253,32,90,135,251,38,92,129,168,117,15,210,93,128,250,39,14,211,169,116,170,119,13,208,249,36,94,131,12,209,171,118,95,130,248,37,178,111,21,200,225,60,70,155,20,201,179,110,71,154,224,61,227,62,68,153,176,109,23,202,69,152,226,63,22,203,177,108,16,205,183,106,67,158,228,57,182,107,17,204,229,56,66,159,65,156,230,59,18,207,181,104,231,58,64,157,180,105,19,206,235,54,76,145,184,101,31,194,77,144,234,55,30,195,185,100,186,103,29,192,233,52,78,147,28,193,187,102,79,146,232,53,73,148,238,51,26,199,189,96,239,50,72,149,188,97,27,198,24,197,191,98,75,150,236,49,190,99,25,196,237,48,74,151,0,222,161,127,95,129,254,32,190,96,31,193,225,63,64,158,97,191,192,30,62,224,159,65,223,1,126,160,128,94,33,255,194,28,99,189,157,67,60,226,124,162,221,3,35,253,130,92,163,125,2,220,252,34,93,131,29,195,188,98,66,156,227,61,153,71,56,230,198,24,103,185,39,249,134,88,120,166,217,7,248,38,89,135,167,121,6,216,70,152,231,57,25,199,184,102,91,133,250,36,4,218,165,123,229,59,68,154,186,100,27,197,58,228,155,69,101,187,196,26,132,90,37,251,219,5,122,164,47,241,142,80,112,174,209,15,145,79,48,238,206,16,111,177,78,144,239,49,17,207,176,110,240,46,81,143,175,113,14,208,237,51,76,146,178,108,19,205,83,141,242,44,12,210,173,115,140,82,45,243,211,13,114,172,50,236,147,77,109,179,204,18,182,104,23,201,233,55,72,150,8,214,169,119,87,137,246,40,215,9,118,168,136,86,41,247,105,183,200,22,54,232,151,73,116,170,213,11,43,245,138,84,202,20,107,181,149,75,52,234,21,203,180,106,74,148,235,53,171,117,10,212,244,42,85,139,0,223,163,124,91,132,248,39,182,105,21,202,237,50,78,145,113,174,210,13,42,245,137,86,199,24,100,187,156,67,63,224,226,61,65,158,185,102,26,197,84,139,247,40,15,208,172,115,147,76,48,239,200,23,107,180,37,250,134,89,126,161,221,2,217,6,122,165,130,93,33,254,111,176,204,19,52,235,151,72,168,119,11,212,243,44,80,143,30,193,189,98,69,154,230,57,59,228,152,71,96,191,195,28,141,82,46,241,214,9,117,170,74,149,233,54,17,206,178,109,252,35,95,128,167,120,4,219,175,112,12,211,244,43,87,136,25,198,186,101,66,157,225,62,222,1,125,162,133,90,38,249,104,183,203,20,51,236,144,79,77,146,238,49,22,201,181,106,251,36,88,135,160,127,3,220,60,227,159,64,103,184,196,27,138,85,41,246,209,14,114,173,118,169,213,10,45,242,142,81,192,31,99,188,155,68,56,231,7,216,164,123,92,131,255,32,177,110,18,205,234,53,73,150,148,75,55,232,207,16,108,179,34,253,129,94,121,166,218,5,229,58,70,153,190,97,29,194,83,140,240,47,8,215,171,116,0,224,221,61,167,71,122,154,83,179,142,110,244,20,41,201,166,70,123,155,1,225,220,60,245,21,40,200,82,178,143,111,81,177,140,108,246,22,43,203,2,226,223,63,165,69,120,152,247,23,42,202,80,176,141,109,164,68,121,153,3,227,222,62,162,66,127,159,5,229,216,56,241,17,44,204,86,182,139,107,4,228,217,57,163,67,126,158,87,183,138,106,240,16,45,205,243,19,46,206,84,180,137,105,160,64,125,157,7,231,218,58,85,181,136,104,242,18,47,207,6,230,219,59,161,65,124,156,89,185,132,100,254,30,35,195,10,234,215,55,173,77,112,144,255,31,34,194,88,184,133,101,172,76,113,145,11,235,214,54,8,232,213,53,175,79,114,146,91,187,134,102,252,28,33,193,174,78,115,147,9,233,212,52,253,29,32,192,90,186,135,103,251,27,38,198,92,188,129,97,168,72,117,149,15,239,210,50,93,189,128,96,250,26,39,199,14,238,211,51,169,73,116,148,170,74,119,151,13,237,208,48,249,25,36,196,94,190,131,99,12,236,209,49,171,75,118,150,95,191,130,98,248,24,37,197,0,225,223,62,163,66,124,157,91,186,132,101,248,25,39,198,182,87,105,136,21,244,202,43,237,12,50,211,78,175,145,112,113,144,174,79,210,51,13,236,42,203,245,20,137,104,86,183,199,38,24,249,100,133,187,90,156,125,67,162,63,222,224,1,226,3,61,220,65,160,158,127,185,88,102,135,26,251,197,36,84,181,139,106,247,22,40,201,15,238,208,49,172,77,115,146,147,114,76,173,48,209,239,14,200,41,23,246,107,138,180,85,37,196,250,27,134,103,89,184,126,159,161,64,221,60,2,227,217,56,6,231,122,155,165,68,130,99,93,188,33,192,254,31,111,142,176,81,204,45,19,242,52,213,235,10,151,118,72,169,168,73,119,150,11,234,212,53,243,18,44,205,80,177,143,110,30,255,193,32,189,92,98,131,69,164,154,123,230,7,57,216,59,218,228,5,152,121,71,166,96,129,191,94,195,34,28,253,141,108,82,179,46,207,241,16,214,55,9,232,117,148,170,75,74,171,149,116,233,8,54,215,17,240,206,47,178,83,109,140,252,29,35,194,95,190,128,97,167,70,120,153,4,229,219,58,0,226,217,59,175,77,118,148,67,161,154,120,236,14,53,215,134,100,95,189,41,203,240,18,197,39,28,254,106,136,179,81,17,243,200,42,190,92,103,133,82,176,139,105,253,31,36,198,151,117,78,172,56,218,225,3,212,54,13,239,123,153,162,64,34,192,251,25,141,111,84,182,97,131,184,90,206,44,23,245,164,70,125,159,11,233,210,48,231,5,62,220,72,170,145,115,51,209,234,8,156,126,69,167,112,146,169,75,223,61,6,228,181,87,108,142,26,248,195,33,246,20,47,205,89,187,128,98,68,166,157,127,235,9,50,208,7,229,222,60,168,74,113,147,194,32,27,249,109,143,180,86,129,99,88,186,46,204,247,21,85,183,140,110,250,24,35,193,22,244,207,45,185,91,96,130,211,49,10,232,124,158,165,71,144,114,73,171,63,221,230,4,102,132,191,93,201,43,16,242,37,199,252,30,138,104,83,177,224,2,57,219,79,173,150,116,163,65,122,152,12,238,213,55,119,149,174,76,216,58,1,227,52,214,237,15,155,121,66,160,241,19,40,202,94,188,135,101,178,80,107,137,29,255,196,38,0,227,219,56,171,72,112,147,75,168,144,115,224,3,59,216,150,117,77,174,61,222,230,5,221,62,6,229,118,149,173,78,49,210,234,9,154,121,65,162,122,153,161,66,209,50,10,233,167,68,124,159,12,239,215,52,236,15,55,212,71,164,156,127,98,129,185,90,201,42,18,241,41,202,242,17,130,97,89,186,244,23,47,204,95,188,132,103,191,92,100,135,20,247,207,44,83,176,136,107,248,27,35,192,24,251,195,32,179,80,104,139,197,38,30,253,110,141,181,86,142,109,85,182,37,198,254,29,196,39,31,252,111,140,180,87,143,108,84,183,36,199,255,28,82,177,137,106,249,26,34,193,25,250,194,33,178,81,105,138,245,22,46,205,94,189,133,102,190,93,101,134,21,246,206,45,99,128,184,91,200,43,19,240,40,203,243,16,131,96,88,187,166,69,125,158,13,238,214,53,237,14,54,213,70,165,157,126,48,211,235,8,155,120,64,163,123,152,160,67,208,51,11,232,151,116,76,175,60,223,231,4,220,63,7,228,119,148,172,79,1,226,218,57,170,73,113,146,74,169,145,114,225,2,58,217,0,228,213,49,183,83,98,134,115,151,166,66,196,32,17,245,230,2,51,215,81,181,132,96,149,113,64,164,34,198,247,19,209,53,4,224,102,130,179,87,162,70,119,147,21,241,192,36,55,211,226,6,128,100,85,177,68,160,145,117,243,23,38,194,191,91,106,142,8,236,221,57,204,40,25,253,123,159,174,74,89,189,140,104,238,10,59,223,42,206,255,27,157,121,72,172,110,138,187,95,217,61,12,232,29,249,200,44,170,78,127,155,136,108,93,185,63,219,234,14,251,31,46,202,76,168,153,125,99,135,182,82,212,48,1,229,16,244,197,33,167,67,114,150,133,97,80,180,50,214,231,3,246,18,35,199,65,165,148,112,178,86,103,131,5,225,208,52,193,37,20,240,118,146,163,71,84,176,129,101,227,7,54,210,39,195,242,22,144,116,69,161,220,56,9,237,107,143,190,90,175,75,122,158,24,252,205,41,58,222,239,11,141,105,88,188,73,173,156,120,254,26,43,207,13,233,216,60,186,94,111,139,126,154,171,79,201,45,28,248,235,15,62,218,92,184,137,109,152,124,77,169,47,203,250,30,0,229,215,50,179,86,100,129,123,158,172,73,200,45,31,250,246,19,33,196,69,160,146,119,141,104,90,191,62,219,233,12,241,20,38,195,66,167,149,112,138,111,93,184,57,220,238,11,7,226,208,53,180,81,99,134,124,153,171,78,207,42,24,253,255,26,40,205,76,169,155,126,132,97,83,182,55,210,224,5,9,236,222,59,186,95,109,136,114,151,165,64,193,36,22,243,14,235,217,60,189,88,106,143,117,144,162,71,198,35,17,244,248,29,47,202,75,174,156,121,131,102,84,177,48,213,231,2,227,6,52,209,80,181,135,98,152,125,79,170,43,206,252,25,21,240,194,39,166,67,113,148,110,139,185,92,221,56,10,239,18,247,197,32,161,68,118,147,105,140,190,91,218,63,13,232,228,1,51,214,87,178,128,101,159,122,72,173,44,201,251,30,28,249,203,46,175,74,120,157,103,130,176,85,212,49,3,230,234,15,61,216,89,188,142,107,145,116,70,163,34,199,245,16,237,8,58,223,94,187,137,108,150,115,65,164,37,192,242,23,27,254,204,41,168,77,127,154,96,133,183,82,211,54,4,225,0,230,209,55,191,89,110,136,99,133,178,84,220,58,13,235,198,32,23,241,121,159,168,78,165,67,116,146,26,252,203,45,145,119,64,166,46,200,255,25,242,20,35,197,77,171,156,122,87,177,134,96,232,14,57,223,52,210,229,3,139,109,90,188,63,217,238,8,128,102,81,183,92,186,141,107,227,5,50,212,249,31,40,206,70,160,151,113,154,124,75,173,37,195,244,18,174,72,127,153,17,247,192,38,205,43,28,250,114,148,163,69,104,142,185,95,215,49,6,224,11,237,218,60,180,82,101,131,126,152,175,73,193,39,16,246,29,251,204,42,162,68,115,149,184,94,105,143,7,225,214,48,219,61,10,236,100,130,181,83,239,9,62,216,80,182,129,103,140,106,93,187,51,213,226,4,41,207,248,30,150,112,71,161,74,172,155,125,245,19,36,194,65,167,144,118,254,24,47,201,34,196,243,21,157,123,76,170,135,97,86,176,56,222,233,15,228,2,53,211,91,189,138,108,208,54,1,231,111,137,190,88,179,85,98,132,12,234,221,59,22,240,199,33,169,79,120,158,117,147,164,66,202,44,27,253,0,231,211,52,187,92,104,143,107,140,184,95,208,55,3,228,214,49,5,226,109,138,190,89,189,90,110,137,6,225,213,50,177,86,98,133,10,237,217,62,218,61,9,238,97,134,178,85,103,128,180,83,220,59,15,232,12,235,223,56,183,80,100,131,127,152,172,75,196,35,23,240,20,243,199,32,175,72,124,155,169,78,122,157,18,245,193,38,194,37,17,246,121,158,170,77,206,41,29,250,117,146,166,65,165,66,118,145,30,249,205,42,24,255,203,44,163,68,112,151,115,148,160,71,200,47,27,252,254,25,45,202,69,162,150,113,149,114,70,161,46,201,253,26,40,207,251,28,147,116,64,167,67,164,144,119,248,31,43,204,79,168,156,123,244,19,39,192,36,195,247,16,159,120,76,171,153,126,74,173,34,197,241,22,242,21,33,198,73,174,154,125,129,102,82,181,58,221,233,14,234,13,57,222,81,182,130,101,87,176,132,99,236,11,63,216,60,219,239,8,135,96,84,179,48,215,227,4,139,108,88,191,91,188,136,111,224,7,51,212,230,1,53,210,93,186,142,105,141,106,94,185,54,209,229,2,0,232,205,37,135,111,74,162,19,251,222,54,148,124,89,177,38,206,235,3,161,73,108,132,53,221,248,16,178,90,127,151,76,164,129,105,203,35,6,238,95,183,146,122,216,48,21,253,106,130,167,79,237,5,32,200,121,145,180,92,254,22,51,219,152,112,85,189,31,247,210,58,139,99,70,174,12,228,193,41,190,86,115,155,57,209,244,28,173,69,96,136,42,194,231,15,212,60,25,241,83,187,158,118,199,47,10,226,64,168,141,101,242,26,63,215,117,157,184,80,225,9,44,196,102,142,171,67,45,197,224,8,170,66,103,143,62,214,243,27,185,81,116,156,11,227,198,46,140,100,65,169,24,240,213,61,159,119,82,186,97,137,172,68,230,14,43,195,114,154,191,87,245,29,56,208,71,175,138,98,192,40,13,229,84,188,153,113,211,59,30,246,181,93,120,144,50,218,255,23,166,78,107,131,33,201,236,4,147,123,94,182,20,252,217,49,128,104,77,165,7,239,202,34,249,17,52,220,126,150,179,91,234,2,39,207,109,133,160,72,223,55,18,250,88,176,149,125,204,36,1,233,75,163,134,110,0,233,207,38,131,106,76,165,27,242,212,61,152,113,87,190,54,223,249,16,181,92,122,147,45,196,226,11,174,71,97,136,108,133,163,74,239,6,32,201,119,158,184,81,244,29,59,210,90,179,149,124,217,48,22,255,65,168,142,103,194,43,13,228,216,49,23,254,91,178,148,125,195,42,12,229,64,169,143,102,238,7,33,200,109,132,162,75,245,28,58,211,118,159,185,80,180,93,123,146,55,222,248,17,175,70,96,137,44,197,227,10,130,107,77,164,1,232,206,39,153,112,86,191,26,243,213,60,173,68,98,139,46,199,225,8,182,95,121,144,53,220,250,19,155,114,84,189,24,241,215,62,128,105,79,166,3,234,204,37,193,40,14,231,66,171,141,100,218,51,21,252,89,176,150,127,247,30,56,209,116,157,187,82,236,5,35,202,111,134,160,73,117,156,186,83,246,31,57,208,110,135,161,72,237,4,34,203,67,170,140,101,192,41,15,230,88,177,151,126,219,50,20,253,25,240,214,63,154,115,85,188,2,235,205,36,129,104,78,167,47,198,224,9,172,69,99,138,52,221,251,18,183,94,120,145,0,234,201,35,143,101,70,172,3,233,202,32,140,102,69,175,6,236,207,37,137,99,64,170,5,239,204,38,138,96,67,169,12,230,197,47,131,105,74,160,15,229,198,44,128,106,73,163,10,224,195,41,133,111,76,166,9,227,192,42,134,108,79,165,24,242,209,59,151,125,94,180,27,241,210,56,148,126,93,183,30,244,215,61,145,123,88,178,29,247,212,62,146,120,91,177,20,254,221,55,155,113,82,184,23,253,222,52,152,114,81,187,18,248,219,49,157,119,84,190,17,251,216,50,158,116,87,189,48,218,249,19,191,85,118,156,51,217,250,16,188,86,117,159,54,220,255,21,185,83,112,154,53,223,252,22,186,80,115,153,60,214,245,31,179,89,122,144,63,213,246,28,176,90,121,147,58,208,243,25,181,95,124,150,57,211,240,26,182,92,127,149,40,194,225,11,167,77,110,132,43,193,226,8,164,78,109,135,46,196,231,13,161,75,104,130,45,199,228,14,162,72,107,129,36,206,237,7,171,65,98,136,39,205,238,4,168,66,97,139,34,200,235,1,173,71,100,142,33,203,232,2,174,68,103,141,0,235,203,32,139,96,64,171,11,224,192,43,128,107,75,160,22,253,221,54,157,118,86,189,29,246,214,61,150,125,93,182,44,199,231,12,167,76,108,135,39,204,236,7,172,71,103,140,58,209,241,26,177,90,122,145,49,218,250,17,186,81,113,154,88,179,147,120,211,56,24,243,83,184,152,115,216,51,19,248,78,165,133,110,197,46,14,229,69,174,142,101,206,37,5,238,116,159,191,84,255,20,52,223,127,148,180,95,244,31,63,212,98,137,169,66,233,2,34,201,105,130,162,73,226,9,41,194,176,91,123,144,59,208,240,27,187,80,112,155,48,219,251,16,166,77,109,134,45,198,230,13,173,70,102,141,38,205,237,6,156,119,87,188,23,252,220,55,151,124,92,183,28,247,215,60,138,97,65,170,1,234,202,33,129,106,74,161,10,225,193,42,232,3,35,200,99,136,168,67,227,8,40,195,104,131,163,72,254,21,53,222,117,158,190,85,245,30,62,213,126,149,181,94,196,47,15,228,79,164,132,111,207,36,4,239,68,175,143,100,210,57,25,242,89,178,146,121,217,50,18,249,82,185,153,114,0,236,197,41,151,123,82,190,51,223,246,26,164,72,97,141,102,138,163,79,241,29,52,216,85,185,144,124,194,46,7,235,204,32,9,229,91,183,158,114,255,19,58,214,104,132,173,65,170,70,111,131,61,209,248,20,153,117,92,176,14,226,203,39,133,105,64,172,18,254,215,59,182,90,115,159,33,205,228,8,227,15,38,202,116,152,177,93,208,60,21,249,71,171,130,110,73,165,140,96,222,50,27,247,122,150,191,83,237,1,40,196,47,195,234,6,184,84,125,145,28,240,217,53,139,103,78,162,23,251,210,62,128,108,69,169,36,200,225,13,179,95,118,154,113,157,180,88,230,10,35,207,66,174,135,107,213,57,16,252,219,55,30,242,76,160,137,101,232,4,45,193,127,147,186,86,189,81,120,148,42,198,239,3,142,98,75,167,25,245,220,48,146,126,87,187,5,233,192,44,161,77,100,136,54,218,243,31,244,24,49,221,99,143,166,74,199,43,2,238,80,188,149,121,94,178,155,119,201,37,12,224,109,129,168,68,250,22,63,211,56,212,253,17,175,67,106,134,11,231,206,34,156,112,89,181,0,237,199,42,147,126,84,185,59,214,252,17,168,69,111,130,118,155,177,92,229,8,34,207,77,160,138,103,222,51,25,244,236,1,43,198,127,146,184,85,215,58,16,253,68,169,131,110,154,119,93,176,9,228,206,35,161,76,102,139,50,223,245,24,197,40,2,239,86,187,145,124,254,19,57,212,109,128,170,71,179,94,116,153,32,205,231,10,136,101,79,162,27,246,220,49,41,196,238,3,186,87,125,144,18,255,213,56,129,108,70,171,95,178,152,117,204,33,11,230,100,137,163,78,247,26,48,221,151,122,80,189,4,233,195,46,172,65,107,134,63,210,248,21,225,12,38,203,114,159,181,88,218,55,29,240,73,164,142,99,123,150,188,81,232,5,47,194,64,173,135,106,211,62,20,249,13,224,202,39,158,115,89,180,54,219,241,28,165,72,98,143,82,191,149,120,193,44,6,235,105,132,174,67,250,23,61,208,36,201,227,14,183,90,112,157,31,242,216,53,140,97,75,166,190,83,121,148,45,192,234,7,133,104,66,175,22,251,209,60,200,37,15,226,91,182,156,113,243,30,52,217,96,141,167,74,0,238,193,47,159,113,94,176,35,205,226,12,188,82,125,147,70,168,135,105,217,55,24,246,101,139,164,74,250,20,59,213,140,98,77,163,19,253,210,60,175,65,110,128,48,222,241,31,202,36,11,229,85,187,148,122,233,7,40,198,118,152,183,89,5,235,196,42,154,116,91,181,38,200,231,9,185,87,120,150,67,173,130,108,220,50,29,243,96,142,161,79,255,17,62,208,137,103,72,166,22,248,215,57,170,68,107,133,53,219,244,26,207,33,14,224,80,190,145,127,236,2,45,195,115,157,178,92,10,228,203,37,149,123,84,186,41,199,232,6,182,88,119,153,76,162,141,99,211,61,18,252,111,129,174,64,240,30,49,223,134,104,71,169,25,247,216,54,165,75,100,138,58,212,251,21,192,46,1,239,95,177,158,112,227,13,34,204,124,146,189,83,15,225,206,32,144,126,81,191,44,194,237,3,179,93,114,156,73,167,136,102,214,56,23,249,106,132,171,69,245,27,52,218,131,109,66,172,28,242,221,51,160,78,97,143,63,209,254,16,197,43,4,234,90,180,155,117,230,8,39,201,121,151,184,86,0,239,195,44,155,116,88,183,43,196,232,7,176,95,115,156,86,185,149,122,205,34,14,225,125,146,190,81,230,9,37,202,172,67,111,128,55,216,244,27,135,104,68,171,28,243,223,48,250,21,57,214,97,142,162,77,209,62,18,253,74,165,137,102,69,170,134,105,222,49,29,242,110,129,173,66,245,26,54,217,19,252,208,63,136,103,75,164,56,215,251,20,163,76,96,143,233,6,42,197,114,157,177,94,194,45,1,238,89,182,154,117,191,80,124,147,36,203,231,8,148,123,87,184,15,224,204,35,138,101,73,166,17,254,210,61,161,78,98,141,58,213,249,22,220,51,31,240,71,168,132,107,247,24,52,219,108,131,175,64,38,201,229,10,189,82,126,145,13,226,206,33,150,121,85,186,112,159,179,92,235,4,40,199,91,180,152,119,192,47,3,236,207,32,12,227,84,187,151,120,228,11,39,200,127,144,188,83,153,118,90,181,2,237,193,46,178,93,113,158,41,198,234,5,99,140,160,79,248,23,59,212,72,167,139,100,211,60,16,255,53,218,246,25,174,65,109,130,30,241,221,50,133,106,70,169,0,240,253,13,231,23,26,234,211,35,46,222,52,196,201,57,187,75,70,182,92,172,161,81,104,152,149,101,143,127,114,130,107,155,150,102,140,124,113,129,184,72,69,181,95,175,162,82,208,32,45,221,55,199,202,58,3,243,254,14,228,20,25,233,214,38,43,219,49,193,204,60,5,245,248,8,226,18,31,239,109,157,144,96,138,122,119,135,190,78,67,179,89,169,164,84,189,77,64,176,90,170,167,87,110,158,147,99,137,121,116,132,6,246,251,11,225,17,28,236,213,37,40,216,50,194,207,63,177,65,76,188,86,166,171,91,98,146,159,111,133,117,120,136,10,250,247,7,237,29,16,224,217,41,36,212,62,206,195,51,218,42,39,215,61,205,192,48,9,249,244,4,238,30,19,227,97,145,156,108,134,118,123,139,178,66,79,191,85,165,168,88,103,151,154,106,128,112,125,141,180,68,73,185,83,163,174,94,220,44,33,209,59,203,198,54,15,255,242,2,232,24,21,229,12,252,241,1,235,27,22,230,223,47,34,210,56,200,197,53,183,71,74,186,80,160,173,93,100,148,153,105,131,115,126,142,0,241,255,14,227,18,28,237,219,42,36,213,56,201,199,54,171,90,84,165,72,185,183,70,112,129,143,126,147,98,108,157,75,186,180,69,168,89,87,166,144,97,111,158,115,130,140,125,224,17,31,238,3,242,252,13,59,202,196,53,216,41,39,214,150,103,105,152,117,132,138,123,77,188,178,67,174,95,81,160,61,204,194,51,222,47,33,208,230,23,25,232,5,244,250,11,221,44,34,211,62,207,193,48,6,247,249,8,229,20,26,235,118,135,137,120,149,100,106,155,173,92,82,163,78,191,177,64,49,192,206,63,210,35,45,220,234,27,21,228,9,248,246,7,154,107,101,148,121,136,134,119,65,176,190,79,162,83,93,172,122,139,133,116,153,104,102,151,161,80,94,175,66,179,189,76,209,32,46,223,50,195,205,60,10,251,245,4,233,24,22,231,167,86,88,169,68,181,187,74,124,141,131,114,159,110,96,145,12,253,243,2,239,30,16,225,215,38,40,217,52,197,203,58,236,29,19,226,15,254,240,1,55,198,200,57,212,37,43,218,71,182,184,73,164,85,91,170,156,109,99,146,127,142,128,113,0,242,249,11,239,29,22,228,195,49,58,200,44,222,213,39,155,105,98,144,116,134,141,127,88,170,161,83,183,69,78,188,43,217,210,32,196,54,61,207,232,26,17,227,7,245,254,12,176,66,73,187,95,173,166,84,115,129,138,120,156,110,101,151,86,164,175,93,185,75,64,178,149,103,108,158,122,136,131,113,205,63,52,198,34,208,219,41,14,252,247,5,225,19,24,234,125,143,132,118,146,96,107,153,190,76,71,181,81,163,168,90,230,20,31,237,9,251,240,2,37,215,220,46,202,56,51,193,172,94,85,167,67,177,186,72,111,157,150,100,128,114,121,139,55,197,206,60,216,42,33,211,244,6,13,255,27,233,226,16,135,117,126,140,104,154,145,99,68,182,189,79,171,89,82,160,28,238,229,23,243,1,10,248,223,45,38,212,48,194,201,59,250,8,3,241,21,231,236,30,57,203,192,50,214,36,47,221,97,147,152,106,142,124,119,133,162,80,91,169,77,191,180,70,209,35,40,218,62,204,199,53,18,224,235,25,253,15,4,246,74,184,179,65,165,87,92,174,137,123,112,130,102,148,159,109,0,243,251,8,235,24,16,227,203,56,48,195,32,211,219,40,139,120,112,131,96,147,155,104,64,179,187,72,171,88,80,163,11,248,240,3,224,19,27,232,192,51,59,200,43,216,208,35,128,115,123,136,107,152,144,99,75,184,176,67,160,83,91,168,22,229,237,30,253,14,6,245,221,46,38,213,54,197,205,62,157,110,102,149,118,133,141,126,86,165,173,94,189,78,70,181,29,238,230,21,246,5,13,254,214,37,45,222,61,206,198,53,150,101,109,158,125,142,134,117,93,174,166,85,182,69,77,190,44,223,215,36,199,52,60,207,231,20,28,239,12,255,247,4,167,84,92,175,76,191,183,68,108,159,151,100,135,116,124,143,39,212,220,47,204,63,55,196,236,31,23,228,7,244,252,15,172,95,87,164,71,180,188,79,103,148,156,111,140,127,119,132,58,201,193,50,209,34,42,217,241,2,10,249,26,233,225,18,177,66,74,185,90,169,161,82,122,137,129,114,145,98,106,153,49,194,202,57,218,41,33,210,250,9,1,242,17,226,234,25,186,73,65,178,81,162,170,89,113,130,138,121,154,105,97,146,0,244,245,1,247,3,2,246,243,7,6,242,4,240,241,5,251,15,14,250,12,248,249,13,8,252,253,9,255,11,10,254,235,31,30,234,28,232,233,29,24,236,237,25,239,27,26,238,16,228,229,17,231,19,18,230,227,23,22,226,20,224,225,21,203,63,62,202,60,200,201,61,56,204,205,57,207,59,58,206,48,196,197,49,199,51,50,198,195,55,54,194,52,192,193,53,32,212,213,33,215,35,34,214,211,39,38,210,36,208,209,37,219,47,46,218,44,216,217,45,40,220,221,41,223,43,42,222,139,127,126,138,124,136,137,125,120,140,141,121,143,123,122,142,112,132,133,113,135,115,114,134,131,119,118,130,116,128,129,117,96,148,149,97,151,99,98,150,147,103,102,146,100,144,145,101,155,111,110,154,108,152,153,109,104,156,157,105,159,107,106,158,64,180,181,65,183,67,66,182,179,71,70,178,68,176,177,69,187,79,78,186,76,184,185,77,72,188,189,73,191,75,74,190,171,95,94,170,92,168,169,93,88,172,173,89,175,91,90,174,80,164,165,81,167,83,82,166,163,87,86,162,84,160,161,85,0,245,247,2,243,6,4,241,251,14,12,249,8,253,255,10,235,30,28,233,24,237,239,26,16,229,231,18,227,22,20,225,203,62,60,201,56,205,207,58,48,197,199,50,195,54,52,193,32,213,215,34,211,38,36,209,219,46,44,217,40,221,223,42,139,126,124,137,120,141,143,122,112,133,135,114,131,118,116,129,96,149,151,98,147,102,100,145,155,110,108,153,104,157,159,106,64,181,183,66,179,70,68,177,187,78,76,185,72,189,191,74,171,94,92,169,88,173,175,90,80,165,167,82,163,86,84,161,11,254,252,9,248,13,15,250,240,5,7,242,3,246,244,1,224,21,23,226,19,230,228,17,27,238,236,25,232,29,31,234,192,53,55,194,51,198,196,49,59,206,204,57,200,61,63,202,43,222,220,41,216,45,47,218,208,37,39,210,35,214,212,33,128,117,119,130,115,134,132,113,123,142,140,121,136,125,127,138,107,158,156,105,152,109,111,154,144,101,103,146,99,150,148,97,75,190,188,73,184,77,79,186,176,69,71,178,67,182,180,65,160,85,87,162,83,166,164,81,91,174,172,89,168,93,95,170,0,246,241,7,255,9,14,248,227,21,18,228,28,234,237,27,219,45,42,220,36,210,213,35,56,206,201,63,199,49,54,192,171,93,90,172,84,162,165,83,72,190,185,79,183,65,70,176,112,134,129,119,143,121,126,136,147,101,98,148,108,154,157,107,75,189,186,76,180,66,69,179,168,94,89,175,87,161,166,80,144,102,97,151,111,153,158,104,115,133,130,116,140,122,125,139,224,22,17,231,31,233,238,24,3,245,242,4,252,10,13,251,59,205,202,60,196,50,53,195,216,46,41,223,39,209,214,32,150,96,103,145,105,159,152,110,117,131,132,114,138,124,123,141,77,187,188,74,178,68,67,181,174,88,95,169,81,167,160,86,61,203,204,58,194,52,51,197,222,40,47,217,33,215,208,38,230,16,23,225,25,239,232,30,5,243,244,2,250,12,11,253,221,43,44,218,34,212,211,37,62,200,207,57,193,55,48,198,6,240,247,1,249,15,8,254,229,19,20,226,26,236,235,29,118,128,135,113,137,127,120,142,149,99,100,146,106,156,155,109,173,91,92,170,82,164,163,85,78,184,191,73,177,71,64,182,0,247,243,4,251,12,8,255,235,28,24,239,16,231,227,20,203,60,56,207,48,199,195,52,32,215,211,36,219,44,40,223,139,124,120,143,112,135,131,116,96,151,147,100,155,108,104,159,64,183,179,68,187,76,72,191,171,92,88,175,80,167,163,84,11,252,248,15,240,7,3,244,224,23,19,228,27,236,232,31,192,55,51,196,59,204,200,63,43,220,216,47,208,39,35,212,128,119,115,132,123,140,136,127,107,156,152,111,144,103,99,148,75,188,184,79,176,71,67,180,160,87,83,164,91,172,168,95,22,225,229,18,237,26,30,233,253,10,14,249,6,241,245,2,221,42,46,217,38,209,213,34,54,193,197,50,205,58,62,201,157,106,110,153,102,145,149,98,118,129,133,114,141,122,126,137,86,161,165,82,173,90,94,169,189,74,78,185,70,177,181,66,29,234,238,25,230,17,21,226,246,1,5,242,13,250,254,9,214,33,37,210,45,218,222,41,61,202,206,57,198,49,53,194,150,97,101,146,109,154,158,105,125,138,142,121,134,113,117,130,93,170,174,89,166,81,85,162,182,65,69,178,77,186,190,73,0,248,237,21,199,63,42,210,147,107,126,134,84,172,185,65,59,195,214,46,252,4,17,233,168,80,69,189,111,151,130,122,118,142,155,99,177,73,92,164,229,29,8,240,34,218,207,55,77,181,160,88,138,114,103,159,222,38,51,203,25,225,244,12,236,20,1,249,43,211,198,62,127,135,146,106,184,64,85,173,215,47,58,194,16,232,253,5,68,188,169,81,131,123,110,150,154,98,119,143,93,165,176,72,9,241,228,28,206,54,35,219,161,89,76,180,102,158,139,115,50,202,223,39,245,13,24,224,197,61,40,208,2,250,239,23,86,174,187,67,145,105,124,132,254,6,19,235,57,193,212,44,109,149,128,120,170,82,71,191,179,75,94,166,116,140,153,97,32,216,205,53,231,31,10,242,136,112,101,157,79,183,162,90,27,227,246,14,220,36,49,201,41,209,196,60,238,22,3,251,186,66,87,175,125,133,144,104,18,234,255,7,213,45,56,192,129,121,108,148,70,190,171,83,95,167,178,74,152,96,117,141,204,52,33,217,11,243,230,30,100,156,137,113,163,91,78,182,247,15,26,226,48,200,221,37,0,249,239,22,195,58,44,213,155,98,116,141,88,161,183,78,43,210,196,61,232,17,7,254,176,73,95,166,115,138,156,101,86,175,185,64,149,108,122,131,205,52,34,219,14,247,225,24,125,132,146,107,190,71,81,168,230,31,9,240,37,220,202,51,172,85,67,186,111,150,128,121,55,206,216,33,244,13,27,226,135,126,104,145,68,189,171,82,28,229,243,10,223,38,48,201,250,3,21,236,57,192,214,47,97,152,142,119,162,91,77,180,209,40,62,199,18,235,253,4,74,179,165,92,137,112,102,159,69,188,170,83,134,127,105,144,222,39,49,200,29,228,242,11,110,151,129,120,173,84,66,187,245,12,26,227,54,207,217,32,19,234,252,5,208,41,63,198,136,113,103,158,75,178,164,93,56,193,215,46,251,2,20,237,163,90,76,181,96,153,143,118,233,16,6,255,42,211,197,60,114,139,157,100,177,72,94,167,194,59,45,212,1,248,238,23,89,160,182,79,154,99,117,140,191,70,80,169,124,133,147,106,36,221,203,50,231,30,8,241,148,109,123,130,87,174,184,65,15,246,224,25,204,53,35,218,0,250,233,19,207,53,38,220,131,121,106,144,76,182,165,95,27,225,242,8,212,46,61,199,152,98,113,139,87,173,190,68,54,204,223,37,249,3,16,234,181,79,92,166,122,128,147,105,45,215,196,62,226,24,11,241,174,84,71,189,97,155,136,114,108,150,133,127,163,89,74,176,239,21,6,252,32,218,201,51,119,141,158,100,184,66,81,171,244,14,29,231,59,193,210,40,90,160,179,73,149,111,124,134,217,35,48,202,22,236,255,5,65,187,168,82,142,116,103,157,194,56,43,209,13,247,228,30,216,34,49,203,23,237,254,4,91,161,178,72,148,110,125,135,195,57,42,208,12,246,229,31,64,186,169,83,143,117,102,156,238,20,7,253,33,219,200,50,109,151,132,126,162,88,75,177,245,15,28,230,58,192,211,41,118,140,159,101,185,67,80,170,180,78,93,167,123,129,146,104,55,205,222,36,248,2,17,235,175,85,70,188,96,154,137,115,44,214,197,63,227,25,10,240,130,120,107,145,77,183,164,94,1,251,232,18,206,52,39,221,153,99,112,138,86,172,191,69,26,224,243,9,213,47,60,198,0,251,235,16,203,48,32,219,139,112,96,155,64,187,171,80,11,240,224,27,192,59,43,208,128,123,107,144,75,176,160,91,22,237,253,6,221,38,54,205,157,102,118,141,86,173,189,70,29,230,246,13,214,45,61,198,150,109,125,134,93,166,182,77,44,215,199,60,231,28,12,247,167,92,76,183,108,151,135,124,39,220,204,55,236,23,7,252,172,87,71,188,103,156,140,119,58,193,209,42,241,10,26,225,177,74,90,161,122,129,145,106,49,202,218,33,250,1,17,234,186,65,81,170,113,138,154,97,88,163,179,72,147,104,120,131,211,40,56,195,24,227,243,8,83,168,184,67,152,99,115,136,216,35,51,200,19,232,248,3,78,181,165,94,133,126,110,149,197,62,46,213,14,245,229,30,69,190,174,85,142,117,101,158,206,53,37,222,5,254,238,21,116,143,159,100,191,68,84,175,255,4,20,239,52,207,223,36,127,132,148,111,180,79,95,164,244,15,31,228,63,196,212,47,98,153,137,114,169,82,66,185,233,18,2,249,34,217,201,50,105,146,130,121,162,89,73,178,226,25,9,242,41,210,194,57,0,252,229,25,215,43,50,206,179,79,86,170,100,152,129,125,123,135,158,98,172,80,73,181,200,52,45,209,31,227,250,6,246,10,19,239,33,221,196,56,69,185,160,92,146,110,119,139,141,113,104,148,90,166,191,67,62,194,219,39,233,21,12,240,241,13,20,232,38,218,195,63,66,190,167,91,149,105,112,140,138,118,111,147,93,161,184,68,57,197,220,32,238,18,11,247,7,251,226,30,208,44,53,201,180,72,81,173,99,159,134,122,124,128,153,101,171,87,78,178,207,51,42,214,24,228,253,1,255,3,26,230,40,212,205,49,76,176,169,85,155,103,126,130,132,120,97,157,83,175,182,74,55,203,210,46,224,28,5,249,9,245,236,16,222,34,59,199,186,70,95,163,109,145,136,116,114,142,151,107,165,89,64,188,193,61,36,216,22,234,243,15,14,242,235,23,217,37,60,192,189,65,88,164,106,150,143,115,117,137,144,108,162,94,71,187,198,58,35,223,17,237,244,8,248,4,29,225,47,211,202,54,75,183,174,82,156,96,121,133,131,127,102,154,84,168,177,77,48,204,213,41,231,27,2,254,0,253,231,26,211,46,52,201,187,70,92,161,104,149,143,114,107,150,140,113,184,69,95,162,208,45,55,202,3,254,228,25,214,43,49,204,5,248,226,31,109,144,138,119,190,67,89,164,189,64,90,167,110,147,137,116,6,251,225,28,213,40,50,207,177,76,86,171,98,159,133,120,10,247,237,16,217,36,62,195,218,39,61,192,9,244,238,19,97,156,134,123,178,79,85,168,103,154,128,125,180,73,83,174,220,33,59,198,15,242,232,21,12,241,235,22,223,34,56,197,183,74,80,173,100,153,131,126,127,130,152,101,172,81,75,182,196,57,35,222,23,234,240,13,20,233,243,14,199,58,32,221,175,82,72,181,124,129,155,102,169,84,78,179,122,135,157,96,18,239,245,8,193,60,38,219,194,63,37,216,17,236,246,11,121,132,158,99,170,87,77,176,206,51,41,212,29,224,250,7,117,136,146,111,166,91,65,188,165,88,66,191,118,139,145,108,30,227,249,4,205,48,42,215,24,229,255,2,203,54,44,209,163,94,68,185,112,141,151,106,115,142,148,105,160,93,71,186,200,53,47,210,27,230,252,1,0,254,225,31,223,33,62,192,163,93,66,188,124,130,157,99,91,165,186,68,132,122,101,155,248,6,25,231,39,217,198,56,182,72,87,169,105,151,136,118,21,235,244,10,202,52,43,213,237,19,12,242,50,204,211,45,78,176,175,81,145,111,112,142,113,143,144,110,174,80,79,177,210,44,51,205,13,243,236,18,42,212,203,53,245,11,20,234,137,119,104,150,86,168,183,73,199,57,38,216,24,230,249,7,100,154,133,123,187,69,90,164,156,98,125,131,67,189,162,92,63,193,222,32,224,30,1,255,226,28,3,253,61,195,220,34,65,191,160,94,158,96,127,129,185,71,88,166,102,152,135,121,26,228,251,5,197,59,36,218,84,170,181,75,139,117,106,148,247,9,22,232,40,214,201,55,15,241,238,16,208,46,49,207,172,82,77,179,115,141,146,108,147,109,114,140,76,178,173,83,48,206,209,47,239,17,14,240,200,54,41,215,23,233,246,8,107,149,138,116,180,74,85,171,37,219,196,58,250,4,27,229,134,120,103,153,89,167,184,70,126,128,159,97,161,95,64,190,221,35,60,194,2,252,227,29,0,255,227,28,219,36,56,199,171,84,72,183,112,143,147,108,75,180,168,87,144,111,115,140,224,31,3,252,59,196,216,39,150,105,117,138,77,178,174,81,61,194,222,33,230,25,5,250,221,34,62,193,6,249,229,26,118,137,149,106,173,82,78,177,49,206,210,45,234,21,9,246,154,101,121,134,65,190,162,93,122,133,153,102,161,94,66,189,209,46,50,205,10,245,233,22,167,88,68,187,124,131,159,96,12,243,239,16,215,40,52,203,236,19,15,240,55,200,212,43,71,184,164,91,156,99,127,128,98,157,129,126,185,70,90,165,201,54,42,213,18,237,241,14,41,214,202,53,242,13,17,238,130,125,97,158,89,166,186,69,244,11,23,232,47,208,204,51,95,160,188,67,132,123,103,152,191,64,92,163,100,155,135,120,20,235,247,8,207,48,44,211,83,172,176,79,136,119,107,148,248,7,27,228,35,220,192,63,24,231,251,4,195,60,32,223,179,76,80,175,104,151,139,116,197,58,38,217,30,225,253,2,110,145,141,114,181,74,86,169,142,113,109,146,85,170,182,73,37,218,198,57,254,1,29,226}; + + +/* + ** this function is used to create galois_mult_8_table[65536] +*/ + +/*int galois_create_mult_tables(int w) + + int j, x, y, logx; + + if (w >= 14) return -1; + + if (galois_mult_tables[w] != NULL) return 0; + galois_mult_tables[w] = (int *) malloc(sizeof(int) * nw[w] * nw[w]); + if (galois_mult_tables[w] == NULL) return -1; + + galois_div_tables[w] = (int *) malloc(sizeof(int) * nw[w] * nw[w]); + if (galois_div_tables[w] == NULL) { + free(galois_mult_tables[w]); + galois_mult_tables[w] = NULL; + return -1; + } + if (galois_log_tables[w] == NULL) { + if (galois_create_log_tables(w) < 0) { + free(galois_mult_tables[w]); + free(galois_div_tables[w]); + galois_mult_tables[w] = NULL; + galois_div_tables[w] = NULL; + return -1; + } + } + + j = 0; + galois_mult_tables[w][j] = 0; + galois_div_tables[w][j] = -1; + j++; + for (y = 1; y < nw[w]; y++) { + galois_mult_tables[w][j] = 0; + galois_div_tables[w][j] = 0; + j++; + } + + for (x = 1; x < nw[w]; x++) { + galois_mult_tables[w][j] = 0; + galois_div_tables[w][j] = -1; + j++; + logx = galois_log_tables[w][x]; + for (y = 1; y < nw[w]; y++) { + galois_mult_tables[w][j] = galois_ilog_tables[w][logx+galois_log_tables[w][y]]; + galois_div_tables[w][j] = galois_ilog_tables[w][logx-galois_log_tables[w][y]]; + j++; + } + } + FILE * fp; + fp = fopen("/home/lixiang/zt_hash/table_result.txt","a"); + int i = 0; + fprintf(fp, "mult_tables:\n"); + for(i = 0; i < nw[w]*nw[w]; i++) + { + fprintf(fp, "%d,", galois_mult_tables[w][i]); + } + fprintf(fp, "\ndiv_tables:\n"); + for(i = 0; i < nw[w]*nw[w]; i++) + { + fprintf(fp, "%d,", galois_div_tables[w][i]); + } + + fprintf(fp, "\nlog_tables:\n"); + for(i = 0; i < nw[w]; i++) + { + fprintf(fp, "%d,", galois_log_tables[w][i]); + } + + fprintf(fp, "\nilog_tables:\n"); + for(i = 0; i < nw[w]*3; i++) + { + fprintf(fp, "%d,", galois_ilog_tables[w][i]); + } + fclose(fp); + return 0; +} +*/ + +#define galois_multtable_8_multiply(x,y) galois_mult_8_table[((x)<<8)|(y)] +/* +inline unsigned char galois_multtable_8_multiply(unsigned char x, unsigned char y) +{ + int index = (x<<8) | y; + return galois_mult_8_table[index]; +} +*/ + +/*int galois_destroy_mult_tables(int w) +{ + return 0; +}*/ + +static inline void zt_hash_arymul(struct zt_state_t * a, struct zt_state_t* b) +{ + struct zt_state_t tmp; + tmp.val=a->val; + a->matrix[0] = galois_multtable_8_multiply(tmp.matrix[0],b->matrix[0])^galois_multtable_8_multiply(tmp.matrix[1],b->matrix[2]); + a->matrix[1] = galois_multtable_8_multiply(tmp.matrix[0],b->matrix[1])^galois_multtable_8_multiply(tmp.matrix[1],b->matrix[3]); + a->matrix[2] = galois_multtable_8_multiply(tmp.matrix[2],b->matrix[0])^galois_multtable_8_multiply(tmp.matrix[3],b->matrix[2]); + a->matrix[3] = galois_multtable_8_multiply(tmp.matrix[2],b->matrix[1])^galois_multtable_8_multiply(tmp.matrix[3],b->matrix[3]); +} + +/* + ** this function is used to create the table[4][256] +*/ +/*void convert(int number, unsigned char * ret) +{ + int i,a[8]; + unsigned char tmp[4]; + for(i = 0; i < 8; i++) + { + a[i] = number%2; + number = number/2; + } + if(a[7] == 0) + { + ret[0] = 2; + ret[1] = 1; + ret[2] = 1; + ret[3] = 0; + } + else + { + ret[0] = 2; + ret[1] = 3; + ret[2] = 1; + ret[3] = 1; + } + for(i = 6; i >= 0; i--) + { + if(a[i] == 0) + { + tmp[0] = 2; + tmp[1] = 1; + tmp[2] = 1; + tmp[3] = 0; + + } + else + { + tmp[0] = 2; + tmp[1] = 3; + tmp[2] = 1; + tmp[3] = 1; + } + zt_hash_arymul(ret, tmp); + } +}*/ + + +/* + ** this function is used to create table[4][256] + */ +/*void zt_hash_create_table() +{ + unsigned char ret[4]={0}; + int i = 0; + FILE * fp; + fp = fopen("/home/lixiang/zt_hash/table.txt","a"); + //galois_create_mult_tables(8); //it should not be a comment + for(i = 0; i < 256; i++) + { + convert(i, ret); + table[i].matrix[0] = ret[0]; + table[i].matrix[1] = ret[1]; + table[i].matrix[2] = ret[2]; + table[i].matrix[3] = ret[3]; + fprintf(fp, "{%d,%d,%d,%d},", table[i].matrix[0], + table[i].matrix[1], + table[i].matrix[2], + table[i].matrix[3]); + } +} + +void zt_hash_destroy_table() +{ + int i = 0; + for(i = 0; i < 33; i++) + { + galois_destroy_mult_tables(i); + } +}*/ + + +inline void zt_hash(struct zt_state_t* array, unsigned char c) +{ + zt_hash_arymul(array, (struct zt_state_t *)(table[c])); +} + +unsigned char ZT_INIT_VAL[4]={1,0,0,1}; +void zt_hash_initial(struct zt_state_t* zt_val) +{ + zt_val->matrix[0] = 1; + zt_val->matrix[1] = 0; + zt_val->matrix[2] = 0; + zt_val->matrix[3] = 1; +} + +int zt_hash_code(struct zt_state_t* zt_val) +{ + int ret; + int tmp[4]; + tmp[0] = zt_val->matrix[0]; + tmp[1] = zt_val->matrix[1]<<8; + tmp[2] = zt_val->matrix[2]<<16; + tmp[3] = zt_val->matrix[3]<<24; + ret = tmp[0]^tmp[1]^tmp[2]^tmp[3]; + return ret; +} + + diff --git a/src/inc_internal/field_stat.h b/src/inc_internal/field_stat.h new file mode 100644 index 0000000..6bdf657 --- /dev/null +++ b/src/inc_internal/field_stat.h @@ -0,0 +1,71 @@ +#ifndef H_SCREEN_STAT_H_INCLUDE +#define H_SCREEN_STAT_H_INCLUDE +#include + +#ifndef __cplusplus +#error("This file should be compiled with C++ compiler") +#endif + +enum field_dsp_style_t +{ + FS_STYLE_FIELD=0, + FS_STYLE_COLUMN, + FS_STYLE_LINE, + FS_STYLE_STATUS +}; +enum field_calc_algo +{ + FS_CALC_CURRENT=0, + FS_CALC_SPEED +}; +enum field_op +{ + FS_OP_ADD=1, + FS_OP_SET +}; + + +typedef void* screen_stat_handle_t; + +enum FS_option +{ + OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout. + PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE. + STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds. + PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1. + CREATE_THREAD,//VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function, + //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0. + ID_INVISBLE,//value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one. +}; + +//Always success. +screen_stat_handle_t FS_create_handle(void); + +int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size); +void FS_start(screen_stat_handle_t handle); +void FS_stop(screen_stat_handle_t* handle); + +//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed. +int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//numerator_id and denominator_id must be column/field/status style. +//scaling: negative value: zoom in; positive value: zoom out; +int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//id: when id's type is FIELD , column_id is ignore. +int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value); + +void FS_passive_output(screen_stat_handle_t handle); + +screen_stat_handle_t init_screen_stat(FILE* output_fp,int stat_cycle,int screen_print_trigger); + +//return field_id >=0 when success, return -1 when failed. +int stat_field_register(screen_stat_handle_t handle,const char* field_name); + +//return >=0 when success, return -1 when failed. +#define FS_OP_TYPE_ADD (FS_OP_ADD) +#define FS_OP_TYPE_SET (FS_OP_SET) +int stat_field_operation(screen_stat_handle_t handle,int field_id,int operation,long long value); + +#endif + diff --git a/src/inc_internal/rulescan.h b/src/inc_internal/rulescan.h index 9230e64..8ee4b80 100644 --- a/src/inc_internal/rulescan.h +++ b/src/inc_internal/rulescan.h @@ -23,10 +23,21 @@ extern "C" { #endif + /* 岻ͬɨ */ + enum ScanType + { + SCANTYPE_DEFAULT = 0, + SCANTYPE_DETAIL_RESULT = 1, + SCANTYPE_REGEX_GROUP = 2 + }; + + #define MAX_REGEX_GROUP_NUM 5 /* ʽֵ֧ĸ */ + #define MAX_EXPR_ITEM_NUM (1U<<3) /* ÿʽMAX_EXPR_ITEM_NUM */ #define MAX_MATCH_POS_NUM 1024 /* ÿصλõĸ */ + #define MATCH_POS_NUM_INC 64 /* ÿصλõĸʼֵֵ */ - /* 岻ͬĹ */ + /* 岻ͬĹ */ const unsigned int RULETYPE_STR = 0; /* ַƹ */ const unsigned int RULETYPE_REG = 1; /* ʽ */ const unsigned int RULETYPE_INT = 2; /* ֵ */ @@ -195,6 +206,17 @@ extern "C" */ void * rulescan_initialize(unsigned int max_thread_num); + /* + ܣ + ɨrulescan_update֮ǰɶεãÿһɨ + + instance[in]: ɨָ룻 + scan_type_flag[in]: ɨ͵ı־Ϣ0λõϢ1λõϢDzϢ2λϢϢ + ֵ + 1ȷã-1ʧܡ + */ + int rulescan_set_param(void * instance, int scan_type_flag); + /* ܣ̬עһʽɨ󡣶ͬһinstanceͬʱж̡߳ diff --git a/test/Makefile b/test/Makefile index 44d1c16..089366a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,6 +2,6 @@ LIBS=../lib/libmaatframe.so INC=-I../inc/ -I/usr/include/MESA/ all: g++ -o maat_test -g -Wall maat_test.cpp $(INC) $(LIBS) - g++ -o digest_gen -g digest_gen.c -I../src/inc_internal/ ../lib/libmaatframe.so + g++ -o digest_gen -g digest_gen.c $(INC) $(LIBS) clean: rm maat_test test.log* -f diff --git a/test/maat_json.json b/test/maat_json.json index 80bf5c2..b133216 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -181,13 +181,122 @@ "table_type": "digest", "table_content": { "raw_len": 1160164, - "digest": "FsOmaK3utZafWYt/i[7203:46299992]", + "digest": "12288:UChtbFS6pypdTy4m2[0:1160163]", "cfds_level": 3 } } ] } ] + }, + { + "compile_id": 128, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "effective_rage": 0, + "user_region": "anything", + "is_valid": "yes", + "groups": [ + { + "group_name": "group_8", + "regions": [ + { + "table_name": "HTTP_REGION", + "table_type": "expr_plus", + "table_content": { + "district": "URL", + "keywords": "abckkk&123", + "expr_type": "and", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + }, + { + "compile_id": 129, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "effective_rage": 0, + "user_region": "utf8_中文", + "is_valid": "yes", + "groups": [ + { + "group_name": "group_9", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "C#中国", + "expr_type": "none", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + }, + { + "compile_id": 130, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "effective_rage": 0, + "user_region": "utf8_维语", + "is_valid": "yes", + "groups": [ + { + "group_name": "group_10", + "regions": [ + { + "table_name": "KEYWORDS_TABLE", + "table_type": "string", + "table_content": { + "keywords": "2010&يىلىدىكى", + "expr_type": "and", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + }, + { + "compile_id": 131, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "effective_rage": 0, + "user_region": "utf8_维语2", + "is_valid": "yes", + "groups": [ + { + "group_name": "group_11", + "regions": [ + { + "table_name": "KEYWORDS_TABLE", + "table_type": "string", + "table_content": { + "keywords": "سىياسىي", + "expr_type": "and", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] } ], "plugin_table": [ diff --git a/test/maat_test.cpp b/test/maat_test.cpp index 4be5a90..7f66b2c 100644 --- a/test/maat_test.cpp +++ b/test/maat_test.cpp @@ -13,7 +13,11 @@ #include #include //fstat #include //fstat - +#include +#include +extern int my_scandir(const char *dir, struct dirent ***namelist, + int(*filter)(const struct dirent *), + int(*compar)(const void *, const void *)); void Maat_read_entry_start_cb(int update_type,void* u_para) { return; @@ -36,113 +40,101 @@ void Maat_read_entry_finish_cb(void* u_para) { return; } -int main() +void print_maat_ret(int ret) { - Maat_feather_t feather=NULL; - int cb_table_id=-1,url_scan_table_id=-1,size_scan_table_id=-1,ip_scan_table_id=-1,digest_scan_table_id=-1; - int ret=-1; - int g_iThreadNum=4; - const char* table_info_path="./table_info.conf"; - const char* json_path="./maat_json.json"; -// const char* ful_cfg_dir="./maat_json.json_iris_tmp/index"; -// const char* inc_cfg_dir="./rules/inc/index"; - const char* log_file="./test.log"; - const char* scan_data="http://www.cyberessays.com/search_results.php?action=search&query=yulingjing,abckkk,1234567"; - const char* digest_test_file="./digest_test.data"; - struct stat digest_fstat; - unsigned long long read_size=0,scan_offset=0; - char digest_test_buff[4096]={0}; - int scan_val=2015; + switch(ret) + { + case -1: + printf("scan error.\n"); + break; + case -2: + printf("hit current region,but not hit compile rule.\n"); + break; + case 0: + printf("nothing hit\n"); + break; + default://>0 + printf("hit %d rules\n",ret); + break; + } + return; +} +const char* print_maat_rule(struct Maat_rule_t* result,int ret) +{ + static char buff[1024]={0}; + int i=0,j=0; + switch(ret) + { + case -1: + snprintf(buff,sizeof(buff),"ret=%d,scan error.",ret); + break; + case -2: + snprintf(buff,sizeof(buff),"ret=%d,hit current region,but not hit compile rule.",ret); + break; + case 0: + snprintf(buff,sizeof(buff),"ret=0,nothing hit."); + break; + default://>0 + j=snprintf(buff,sizeof(buff),"hit %d rules, hit ruleid=",ret); + for(i=0;i0 - printf("hit %d rules\n",ret); - break; - } + ret=Maat_scan_intval(feather, table_id, scan_val, result,4,mid, 0); + print_maat_ret(ret); } - Maat_clean_status(&mid); - size_scan_table_id=Maat_table_register(feather,"CONTENT_SIZE"); - if(size_scan_table_id==-1) + return ret; +} +int test_str_stream_scan(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + const char* scan_data="http://www.cyberessays.com/search_results.php?action=search&query=yulingjing,abckkk,1234567"; + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) { - printf("Database table CONTENT_SIZE register failed."); - + printf("Database table %s register failed.\n",table_name); + return -1; } - else - { - ret=Maat_scan_intval(feather, size_scan_table_id, scan_val, result,4,&mid, 0); - switch(ret) - { - case -1: - printf("scan error.\n"); - break; - case -2: - printf("hit current region,but not hit compile rule.\n"); - break; - case 0: - printf("nothing hit\n"); - break; - default://>0 - printf("hit %d rules\n",ret); - break; - } - } - Maat_clean_status(&mid); struct Maat_hit_detail_t *hit_detail=(struct Maat_hit_detail_t *)malloc(sizeof(struct Maat_hit_detail_t)*10); - stream_para_t sp=Maat_stream_scan_string_start(feather,url_scan_table_id,0); + stream_para_t sp=Maat_stream_scan_string_start(feather,table_id,0); int detail_ret=0; if(sp==NULL) { @@ -151,15 +143,21 @@ int main() } ret=Maat_stream_scan_string_detail(&sp,CHARSET_NONE,"www.cyberessays.com", strlen("www.cyberessays.com") ,result,4,hit_detail,10 - ,&detail_ret,&mid); + ,&detail_ret,mid); ret=Maat_stream_scan_string_detail(&sp,CHARSET_NONE,scan_data, strlen(scan_data) ,result,4,hit_detail,10 - ,&detail_ret,&mid); + ,&detail_ret,mid); Maat_stream_scan_string_end(&sp); - - struct ipaddr ipv4_addr,ipv6_addr; + free(hit_detail); + print_maat_ret(ret); + return ret; +} +int test_ipv4_scan(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + struct ipaddr ipv4_addr; struct stream_tuple4_v4 v4_addr; - struct stream_tuple4_v6 v6_addr; ipv4_addr.addrtype=ADDR_TYPE_IPV4; inet_pton(AF_INET,"10.0.6.205",&(v4_addr.saddr)); v4_addr.source=htons(50001); @@ -167,30 +165,45 @@ int main() v4_addr.dest=htons(80); ipv4_addr.v4=&v4_addr; - ip_scan_table_id=Maat_table_register(feather,"IP_CONFIG"); - if(ip_scan_table_id==-1) + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) { - printf("Database table IP_CONFIG register failed."); + printf("Database table %s register failed.\n",table_name); } else { - ret=Maat_scan_proto_addr(feather,ip_scan_table_id,&ipv4_addr,6,result,4, &mid,0); + ret=Maat_scan_proto_addr(feather,table_id,&ipv4_addr,6,result,4, mid,0); if(ret>0) { printf("ipv4 scan hit compile rule id %d.\n",result[0].config_id); } } - Maat_clean_status(&mid); + return ret; +} +int test_ipv6_scan(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + struct ipaddr ipv6_addr; + struct stream_tuple4_v6 v6_addr; + ipv6_addr.addrtype=ADDR_TYPE_IPV6; inet_pton(AF_INET6,"2001:da8:205:1::101",&(v6_addr.saddr)); v6_addr.source=htons(50001); inet_pton(AF_INET6,"2001:da8:205:1::102",&(v6_addr.daddr)); v6_addr.dest=htons(80); ipv6_addr.v6=&v6_addr; - if(ip_scan_table_id>=0) + + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) { - ret=Maat_scan_proto_addr(feather,ip_scan_table_id,&ipv6_addr,6,result,4, &mid,0); + printf("Database table %s register failed.\n",table_name); + + } + else + { + ret=Maat_scan_proto_addr(feather,table_id,&ipv6_addr,6,result,4, mid,0); if(ret==-2) { printf("ipv6 scan hit region.\n"); @@ -201,12 +214,22 @@ int main() } } - Maat_clean_status(&mid); + return ret; +} +int test_digest_scan(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + int table_id=0,ret=0; + const char* digest_test_file="./digest_test.data"; + struct stat digest_fstat; + unsigned long long read_size=0,scan_offset=0; + char digest_test_buff[4096]={0}; - digest_scan_table_id=Maat_table_register(feather, "FILE_DIGEST"); - if(digest_scan_table_id<0) + struct Maat_rule_t result[4]; + stream_para_t sp=NULL; + table_id=Maat_table_register(feather, table_name); + if(table_id<0) { - printf("registe table FILE_DIGEST error.\n"); + printf("registe table %s error.\n",table_name); return 0; } ret=stat(digest_test_file,&digest_fstat); @@ -218,11 +241,11 @@ int main() FILE* fp=fopen(digest_test_file,"r"); if(fp!=NULL) { - sp=Maat_stream_scan_digest_start(feather, digest_scan_table_id, digest_fstat.st_size, 0); + sp=Maat_stream_scan_digest_start(feather, table_id, digest_fstat.st_size, 0); while(0==feof(fp)) { read_size=fread(digest_test_buff,1,sizeof(digest_test_buff),fp); - ret=Maat_stream_scan_digest(&sp, digest_test_buff, read_size, scan_offset, result,4,&mid); + ret=Maat_stream_scan_digest(&sp, digest_test_buff, read_size, scan_offset, result,4,mid); scan_offset+=read_size; if(ret>0) { @@ -237,8 +260,218 @@ int main() printf("fopen %s error.\n",digest_test_file); } Maat_stream_scan_string_end(&sp); - Maat_clean_status(&mid); - Maat_burn_feather(feather); - free(hit_detail); + return ret; +} +int test_plugin_table(Maat_feather_t feather,const char* table_name,void* logger) +{ + int table_id=0,ret=0; + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) + { + printf("Database table %s register failed.\n",table_name); + } + else + { + ret=Maat_table_callback_register(feather, table_id, + Maat_read_entry_start_cb, + Maat_read_entry_cb, + Maat_read_entry_finish_cb, + logger); + if(ret<0) + { + printf("Maat callback register table %s error.\n",table_name); + } + } + return ret; +} +int test_url_encode(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + const char* url_utf8="www.google.com/?q=C%23%E4%B8%AD%E5%9B%BD"; + const char* url_gb2312="www.baidu.com/?wd=C%23%D6%D0%B9%FA"; + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + int found_pos[4]; + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) + { + printf("Database table %s register failed.",table_name); + return -1; + } + ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, url_utf8, strlen(url_utf8), + result,found_pos, 4, + mid, 0); + printf("URL encode scan utf8 url %s\n",print_maat_rule(result,ret)); + + ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, url_gb2312, strlen(url_gb2312), + result,found_pos, 4, + mid, 0); + printf("URL encode scan gb2312 url %s\n",print_maat_rule(result,ret)); + + return 0; +} +int test_unicode_esc(Maat_feather_t feather,const char* table_name,scan_status_t* mid) +{ + const char* test_data_dir="./testdata_uni2ascii"; + struct dirent **namelist; + FILE* fp=NULL; + char file_path[256]={0}; + char buff[4096]; + size_t read_len=0; + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + stream_para_t sp=NULL; + int found_pos[4]; + int n=0,i=0; + table_id=Maat_table_register(feather,table_name); + if(table_id==-1) + { + printf("Database table %s register failed in function %s.\n",table_name,__FUNCTION__); + return -1; + } + n = my_scandir(test_data_dir, &namelist, NULL, (int (*)(const void*, const void*))alphasort); + if(n<0) + { + printf("%s open dir %s error.\n",__FUNCTION__,test_data_dir); + return -1; + } + for(i=0;id_name, ".") == 0) || (strcmp(namelist[i]->d_name, "..") == 0)) + { + continue; + } + snprintf(file_path,sizeof(file_path),"%s/%s",test_data_dir,namelist[i]->d_name); + fp=fopen(file_path,"rb"); + if(fp==NULL) + { + printf("fopen %s error.\n",file_path);; + continue; + } + printf("%s processing %s\n",__FUNCTION__,file_path); + sp=Maat_stream_scan_string_start(feather,table_id,0); + if(sp==NULL) + { + printf("stream scan start failed.\n"); + continue; + } + read_len=fread(buff,1,sizeof(buff),fp); + while(read_len>0) + { + + ret=Maat_stream_scan_string(&sp,CHARSET_NONE,buff,read_len + ,result,found_pos,4,mid); + read_len=fread(buff,1,sizeof(buff),fp); + if(ret>0) + { + printf("UNI2ASCII file %s,%s\n",file_path,print_maat_rule(result,ret)); + } + } + Maat_stream_scan_string_end(&sp); + fclose(fp); + + } + for(i=0;i0) + { + printf("Should not hit without setting district.\n"); + return -1; + } + ret=Maat_set_scan_status(feather, mid, MAAT_SET_SCAN_DISTRICT,region_name,strlen(region_name)+1); + if(ret<0) + { + printf("set MAAT_SET_SCAN_DISTRICT failed.\n"); + return -1; + } + ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, scan_data, strlen(scan_data), + result,found_pos, 4, + mid, 0); + if(ret>0) + { + printf("Hit expr_plus rule %d.\n",result[0].config_id); + } + return ret; + +} +int main(int argc,char* argv[]) +{ + Maat_feather_t feather=NULL; + int g_iThreadNum=4; + const char* table_info_path="./table_info.conf"; + const char* json_path="./maat_json.json"; +// const char* ful_cfg_dir="./maat_json.json_iris_tmp/index"; +// const char* inc_cfg_dir="./rules/inc/index"; + const char* log_file="./test.log"; + const char* stat_file="./scan_staus.log"; + int scan_detail=0; + scan_status_t mid=NULL; + void *logger=MESA_create_runtime_log_handle(log_file,0); + + feather=Maat_feather(g_iThreadNum, table_info_path, logger); + Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, json_path, strlen(json_path)+1); + Maat_set_feather_opt(feather, MAAT_OPT_STAT_FILE_PATH, stat_file, strlen(stat_file)+1); + Maat_set_feather_opt(feather, MAAT_OPT_STAT_ON, NULL, 0); + Maat_set_feather_opt(feather, MAAT_OPT_PERF_ON, NULL, 0); + Maat_set_feather_opt(feather, MAAT_OPT_SCAN_DETAIL, &scan_detail, sizeof(scan_detail)); + Maat_initiate_feather(feather); + + if(feather==NULL) + { + printf("Maat initial error, see %s\n",log_file); + return -1; + } + test_plugin_table(feather, "QD_ENTRY_INFO",logger); + + test_string_full_scan(feather, "HTTP_URL", &mid); + //not clean status here, to test_ipv4_scan make hit compile rule. + test_ipv4_scan(feather, "IP_CONFIG", &mid); + Maat_clean_status(&mid); + + + test_intval_scan(feather,"CONTENT_SIZE" , &mid); + Maat_clean_status(&mid); + + + test_ipv6_scan(feather, "IP_CONFIG", &mid); + Maat_clean_status(&mid); + + test_digest_scan(feather,"FILE_DIGEST", &mid); + Maat_clean_status(&mid); + + test_expr_plus(feather, "HTTP_REGION", &mid); + Maat_clean_status(&mid); + + test_url_encode(feather, "HTTP_URL", &mid); + Maat_clean_status(&mid); + + test_unicode_esc(feather,"KEYWORDS_TABLE",&mid); + Maat_clean_status(&mid); + + sleep(4); + + Maat_burn_feather(feather); + return 0; } diff --git a/test/table_info.conf b/test/table_info.conf index 7ce9a2e..a4cb5b9 100644 --- a/test/table_info.conf +++ b/test/table_info.conf @@ -1,16 +1,17 @@ #each collumn seperate with '\t' #id (0~65535) #name string -#type one of ip,expr,digest,intval,compile or plugin +#type one of ip,expr,expr_plus,digest,intval,compile or plugin #src_charset one of GBK,BIG5,UNICODE,UTF8 #dst_charset combined by GBK,BIG5,UNICODE,UTF8,seperate with '/' #do_merege yes or no #id name type src_charset dst_charset do_merge 0 COMPILE compile GBK GBK no 0 1 GROUP group GBK GBK no 0 -2 HTTP_URL expr GBK GBK/BIG5/UNICODE/UTF8 yes 128 -3 KEYWORDS_TABLE expr GBK GBK/BIG5/UNICODE/UTF8 yes 0 +2 HTTP_URL expr UTF8 GBK/BIG5/UNICODE/UTF8/url_encode_gb2312/url_encode_utf8 yes 128 +3 KEYWORDS_TABLE expr UTF8 GBK/BIG5/UNICODE/UTF8/unicode_ascii_esc/unicode_ascii_aligned/unicode_ncr_dec/unicode_ncr_hex yes 0 4 IP_CONFIG ip GBK GBK no 0 5 CONTENT_SIZE intval GBK GBK no 0 6 QD_ENTRY_INFO plugin GBK GBK no 0 7 FILE_DIGEST digest GBK GBK no 0 +8 HTTP_REGION expr_plus GBK GBK no 0 diff --git a/test/testdata_uni2ascii/original_Uygur_webpage.html b/test/testdata_uni2ascii/original_Uygur_webpage.html new file mode 100644 index 0000000..a3e6169 --- /dev/null +++ b/test/testdata_uni2ascii/original_Uygur_webpage.html @@ -0,0 +1,166 @@ + + + + + مەركىزىي خىزمەتلەرنى چۆرىدەپ ئەقىل كۆرسىتىش، ۋەزىپىسىنى بەجانىدىل ئادا قىلىپ دادىل زىممىگە ئېلىش- تەڭرىتاغ تورى + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + +
+ + + +
+
+
+
    +
    +
    +
      +
    • +
    +
    +
    +
    +
    + +
    + +
    +
    + + +

    + مەركىزىي خىزمەتلەرنى چۆرىدەپ ئەقىل كۆرسىتىش، ۋەزىپىسىنى بەجانىدىل ئادا قىلىپ دادىل زىممىگە ئېلىش +

    + بۇئايشەم2016-03-31 11:17:39شىنجاڭ گېزىتى +
    +
    +

     ئاپتونوم رايوننىڭ 2010–يىلىدىكى ئاپتونوم رايونلۇق پارتكوم سىياسىي كېڭەش خىزمىتى يىغىنىدىن بۇيانقى سىياسىي كېڭەش خىزمىتى توغرىسىدا ئومۇمىي بايان

    +

    ياۋ تۇڭ

    +

        ‹‹قەلبلەرنى مۇجەسسەملەش، ئەقىل كۆرسىتىش، كۈچ قوشۇش›› ج ك پ مەركىزىي كومىتېتى سىياسىي بىيۇروسىنىڭ ئەزاسى، ئاپتونوم رايونلۇق پارتكومنىڭ شۇجىسى جاڭ چۈنشيەننىڭ سىياسىي كېڭەشكە قويغان بۇ تەلىپى ئاپتونوم رايوننىڭ سىياسىي كېڭەش خىزمىتىنىڭ يۆنىلىشىنى كۆرسىتىپ بېرىپ، ئۇنى پىرىنسىپ بىلەن تەمىنلەپ، ئەزالارنىڭ يېڭى ۋەزىيەتتە سىياسىي كېڭەش خىزمىتىنى ياخشى ئىشلەش ئىشەنچى ۋە ئىرادىسىنى كۈچەيتتى.

    +

        ئاپتونوم رايونلۇق پارتكوم سىياسىي كېڭەش خىزمىتىگە ئىزچىل يۈكسەك ئەھمىيەت بېرىپ كەلدى، شۇجى جاڭ چۈنشيەن سىياسىي كېڭەش خىزمىتىگە ناھايىتى كۆڭۈل بۆلدى ۋە ئۇنى قوللىدى، 2010 – يىلى ئاپتونوم رايونلۇق پارتكومنىڭ سىياسىي كېڭەش خىزمىتى يىغىنى ئېچىلغاندىن بۇيان، شۇجى جاڭ چۈنشيەن سىياسىي كېڭەش خىزمىتىنى كۈچەيتىش توغرىسىدا كۆپ قېتىم تەستىقىي يوليۇرۇق بەردى.

    +

        نەچچە يىلدىن بۇيان ئاپتونوم رايونلۇق سىياسىي كېڭەش پارتىيە رەھبەرلىكىدە چىڭ تۇرۇشنى باشتىن – ئاخىر ۋەزىپىسىنى ئادا قىلىشنىڭ بىرىنچى تەلىپى قىلىپ، سىياسىي كېڭەشنىڭ ۋەتەنپەرۋەرلىك بىرلىك سەپ تەشكىلاتىلىق مۇھىم رولىنى تولۇق جارى قىلدۇرۇپ، ئورتاق تونۇشنى كەڭ دائىرىدە مۇجەسسەملىدى؛ دىققەتنى ئىجتىمائىي مۇقىملىق ۋە ئەبەدىي ئەمىنلىككە مەركەزلەشتۈرۈپ، دائىمىي كومىتېت يىغىنى ئېچىپ، بىر قاتار مۇھىم مەسىلىلەر توغرىسىدا تەدبىر، تەكلىپلەرنى ئوتتۇرىغا قويدى؛ ئايلىق كېڭىشىش سۆھبەت يىغىنى ئېچىشنى ئىجادىي يولغا قويۇپ، كېڭىشىپ بىرلىككە كەلگەن پىكىرلەرنى ئاپتونوم رايونلۇق پارتكوم، خەلق ھۆكۈمىتىنىڭ پايدىلىنىشىغا سۇندى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەشنىڭ سىياسىي كېڭەش شىنجاڭ ئۇيغۇر ئاپتونوم رايونلۇق 11 – نۆۋەتلىك كومىتېتى 1 – يىغىنىدىن بۇيانقى ۋەزىپىسىنى ئادا قىلىش خاتىرىسىگە نەزەر سالغاندا، كۆپلىگەن تەكلىپ، تەۋسىيەلەر، بىر قاتار تەكشۈرۈپ تەتقىق قىلىش دوكلاتلىرىنىڭ ھەممىسىدە شىنجاڭدىكى ھەر دەرىجىلىك سىياسىي كېڭەش تەشكىلاتلىرى ۋە سىياسىي كېڭەش ئەزالىرىنىڭ شىنجاڭنىڭ ئىقتىسادىي، ئىجتىمائىي تەرەققىياتى ئۈچۈن قەلبلەرنى مۇجەسسەملەپ، ئەقىل كۆرسىتىپ، كۈچ چىقارغانلىقىدىن ئىبارەت جانلىق ئەمەلىيەت خاتىرىلەنگەن بولۇپ، بۇلار شىنجاڭدىكى ھەر دەرىجىلىك سىياسىي كېڭەش تەشكىلاتلىرى ۋە سىياسىي كېڭەش ئەزالىرىنىڭ دىققەتنى ئاپتونوم رايوننىڭ مەركىزىي خىزمىتىگە مەركەزلەشتۈرۈپ فۇنكسىيەسىنى ئادا قىلىپ، سىياسىي كېڭەشنىڭ كېڭىشىش ئاساسىدىكى دېموكراتىيە قەدىمىنى ئىلگىرى سۈرۈپ، ئىستىل ۋە ئىقتىدار قۇرۇلۇشىنى كۈچەيتىپ، ئەمەلىي ئۈنۈمنى ئاشۇرۇش داۋامىدىكى مەزمۇت قەدەملىرىنىڭ شاھىتى.

    +

        كۈچنى مەركەزلەشتۈرۈپ، ئىتتىپاقلىقنى ئىلگىرى سۈرۈپ، قەلبلەرنى مۇجەسسەملەپ، بىرلىكتە گۈزەل شىنجاڭ قۇرۇپ چىقىش

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەشنىڭ ئەزاسى ۋېي تيەنجې كېسەللىك سەۋەبىدىن نامراتلىشىپ كەتكەن بىر قازاق ئائىلىسىنىڭ قىيىنچىلىقتىن قۇتۇلۇشىغا 20 يىل ياردەم بەردى، ئەڭ دەسلەپتە مەبلەغ چىقىرىپ يېڭى ئۆي سېلىپ بېرىش، قوي ئېلىپ بېرىشتىن، ئەر خوجايىننىڭ قومۇل شەھىرىدە مۇقىم خىزمەت تېپىپ، ئولتۇراقلىشىشى ۋە ئۇنىڭ ئىككى بالىسىنىڭ ئوتتۇرا مەكتەپنى، ئالىي مەكتەپنى تاماملاپ، خىزمەتكە چىقىشىغىچە ئۇلارغا ئىزچىل ئىقتىسادىي جەھەتتىن ياردەم قىلدى. چىڭگىل ناھىيەلىك سىياسىي كېڭەشنىڭ ئەزاسى ئامىنە ساۋۇت 50 ياشتىن ئاشقان، ئائىلە ئەھۋالى ئانچە ياخشى بولمىغان يەككە سودا – سانائەتچى، ئۇ ئىقتىسادچانلىق بىلەن تۇرمۇش كەچۈرۈپ، كۆپ يىللاردىن بۇيان يىغقان 100 مىڭ يۈەندىن كۆپرەك پۇلىغا كىچىك چىڭگىل دەرياسىغا پولات ئارغامچىلىق ئاسما كۆۋرۈك سالدۇرۇپ، ئىككى قىرغاقتىكى ئۈچ كەنتتىكى دېھقان – چارۋىچىلارنىڭ يول يۈرۈشىگە زور قولايلىق يارىتىپ بەردى...

    +

        يېقىنقى يىللاردىن بۇيان ھەر مىللەت، ھەر ساھە سىياسىي كېڭەش ئەزالىرى مىللەتلەر ئىتتىپاقلىقىنى باشلامچىلىق بىلەن قوغداپ، مىللەتلەر ئىتتىپاقلىقىغا بۇزغۇنچىلىق قىلىدىغان بارلىق سۆز، ھەرىكەتلەرگە بايرىقى روشەن ھالدا قارشى تۇرۇپ، ئەمەلىي ھەرىكىتى بىلەن مىللەتلەرنىڭ ئىناق ئۆتۈشى، بىر ياقىدىن باش چىقىرىشى، ئىناق راۋاجلىنىشىغا تۈرتكە بولۇپ، پارتىيە – گۇرۇھلار، تەشكىلاتلار، ھەر مىللەت، ھەر قاتلامدىكىلەرنىڭ بۈيۈك ئىتتىپاقلىقى، بۈيۈك بىرلىشىشىنى ئىلگىرى سۈردى.

    +

        2016 – يىلى 1 – ئايدا ئاپتونوم رايونلۇق سىياسىي كېڭەش بەنگۇڭتىڭى رەھبەرلىرى سىياسىي كېڭەش ئورگىنىدىن مارالبېشى ناھىيەسىنىڭ دۆلەتباغ يېزىسى قۇرۇقتېرەك كەنتىدە تۇرۇشلۇق خىزمەت گۇرۇپپىسىدىكىلەر توغرىسىدا يېزىلغان بىرلەشمە ئىمزالىق خەتنى تاپشۇرۇۋالدى، خەتنى مەزكۇر كەنتتىكى ‹‹تۆت پېشقەدەم››لەر، دىنىي زاتلار ۋە ئامما ۋەكىلىدىن بولۇپ 17 كىشى بىرلىشىپ يازغان بولۇپ، ئۇلار خەتتە پۈتۈن كەنتتىكىلەرگە ۋاكالىتەن كۈچلۈك ئارزۇسىنى ئىپادىلەپ: ‹‹كەنتتە تۇرۇشلۇق كادىر ئېنگۇسۇم زەينىدىننىڭ كەنتىمىزدە يەنە داۋاملىق بىر يىل تۇرۇشىنى ئۈمىد قىلىمىز›› دەپ يازغانىدى.

    +

        ئىككى يىلدىن بۇيان ئاپتونوم رايونلۇق پارتكومنىڭ بىر تۇتاش ئورۇنلاشتۇرۇشى بويىچە شىنجاڭدىكى ھەر دەرىجىلىك سىياسىي كېڭەش تەشكىلاتلىرىدىن 1900دىن كۆپرەك سىياسىي كېڭەش ئەزاسى ۋە 630دىن كۆپرەك سىياسىي كېڭەش كادىرى شىنجاڭدىكى 14 ۋىلايەت، ئوبلاست، شەھەردىكى 1066 كەنتكە چوڭقۇر چۆكۈپ، ئۈچ ئەل پائالىيىتىنى كەڭ قانات يايدۇرۇپ، ئامما بىلەن تاماقتا، ئەمگەكتە بىللە بولۇپ، ئەڭ زور دەرىجىدە ئەلرايىنى مۇجەسسەملەپ، ئاممىنىڭ كۆڭلىنى ئۇتۇپ، ھەر مىللەت ئاممىغا سىياسىي كېڭەشنىڭ ئۆزلىرىگە ناھايىتى يېقىن ئىكەنلىكىنى ھەقىقىي ھېس قىلدۇردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش يەنە پارتىيە – گۇرۇھلار، تەشكىلاتلار ھەمكارلىقىنى كۈچەيتىشنى مۇھىم خىزمەت قىلىپ، دېموكراتىك پارتىيە – گۇرۇھلار، سودا – سانائەتچىلەر بىرلەشمىسى، خەلق تەشكىلاتلىرى ۋە پارتىيە – گۇرۇھسىز زاتلارنىڭ دېموكراتىك ھوقۇقىغا تولۇق ھۆرمەت قىلىپ، تەتقىق قىلىش، كېڭىشىش ئاساسىدا پىلان تۈزۈش قاتارلىق مۇھىم ئىشلاردا ئۇلاردىن تەكلىپ – پىكىر ئېلىشقا ئەھمىيەت بېرىپ، ئۇلارنىڭ ۋەزىپىسىنى ئۈنۈملۈك ئادا قىلىشىغا پائال سەھنە ھازىرلاپ بېرىپ، ئاپتونوم رايوننىڭ ئىسلاھات، تەرەققىيات، مۇقىملىقىغا ئەقىل – پاراسىتى ۋە كۈچىنى بېغىشلىدى.

    +

        ۋەزىپىلەرنى دادىل زىممىگە ئېلىپ، ياخشى ئەقىل كۆرسىتىپ، ئىناقلىقنى ئىلگىرى سۈرۈپ، ئەبەدىي ئەمىنلىكنى قوغداش

    +

        مەملىكەتلىك سىياسىي كېڭەشنىڭ شىنجاڭدىكى ئەزاسى، ئاپتونوم رايونلۇق سىياسىي كېڭەشنىڭ رەئىسى نۇرلان ئابىلمەجىن 12 – مارت سىياسىي كېڭەش مەملىكەتلىك 12 – نۆۋەتلىك كومىتېتىنىڭ 4 – يىغىنىدا ‹‹ئەسەبىيلىكنى تۈگىتىشنى چوڭقۇر ئىلگىرى سۈرۈپ، دۆلەتنىڭ بىخەتەرلىكىنى قەتئىي قوغدايلى›› دېگەن تېمىدا سۆز قىلىپ، دۆلەتنىڭ ئەڭ يۇقىرى كېڭىشىش سەھنىسىدە دىن ئەسەبىيلىكى ئىدىيەسىدىن ئىبارەت ‹‹يامان سۈپەتلىك ئۆسمە››نى يوقىتىپ، دۆلەتنىڭ بىخەتەرلىكىنى قوغداپ، ‹‹بىر بەلباغ، بىر يول›› ئىستراتېگىيەسىنى ئوڭۇشلۇق يولغا قويۇشقا كاپالەتلىك قىلىشنى ئوتتۇرىغا قويدى.

    +

        ‹‹شىنجاڭ ئاۋازى›› خەلق سارىيىدا ياڭرىدى، بۇ شىنجاڭدىكى 23 مىليون ھەر مىللەت ئاممىنىڭ ئورتاق قەلب ساداسى! يېقىنقى نەچچە يىلدىن بۇيان ئاپتونوم رايونلۇق سىياسىي كېڭەش ئىجتىمائىي مۇقىملىق ۋە ئەبەدىي ئەمىنلىكتىن ئىبارەت بۇ باش نىشاننى چۆرىدەپ، ‹‹ئۈچ خىل كۈچ››كە زەربە بېرىش، دىن ئەسەبىيلىكى ئىدىيەسىنىڭ سىڭىپ كىرىشىنى چەكلەش، دىن ئىناقلىقىغا تەسىر يەتكۈزىدىغان ئامىللارنى تۈگىتىش، تىنچ شىنجاڭ قۇرۇشنى ئىلگىرى سۈرۈش قاتارلىق تېمىلار بويىچە تۈرلۈك تەكشۈرۈپ تەتقىق قىلىشنى قانات يايدۇرۇپ، ‹‹سىياسىي كېڭەش ساداسى››نى ياڭراتتى.

    +

        ‹‹يېزىلاردىكى 80 –، 90 – يىللاردا تۇغۇلغانلارغا قارىتىلغان قانۇن – تۈزۈم تەربىيەسى ۋە ئىشقا ئورۇنلاشتۇرۇش مۇلازىمىتى ئۇزاق ئۈنۈملۈك خىزمەت مېخانىزمىنى ئورنىتىپ، جەمئىيەتنىڭ ئەبەدىي ئەمىنلىكىگە تەسىر يەتكۈزۈۋاتقان يوشۇرۇن ئامىللارنى مەنبەدىن تۈگىتىش كېرەك››؛ ‹‹جەنۇبىي شىنجاڭدىكى ئاز سانلىق مىللەت ئاممىنىڭ مەدەنىيەت ساپاسى ۋە تەربىيەلىنىش دەرىجىسىنى ئۆستۈرۈپ، توققۇز يىللىق مەجبۇرىيەت مائارىپىنى دەل جايىدا ئەمەلىيلەشتۈرۈش، جەنۇبىي شىنجاڭدىكى ئۈچ ۋىلايەت، بىر ئوبلاستتا 12 يىللىق ھەقسىز مەجبۇرىيەت مائارىپىنى تېز ئەمەلىيلەشتۈرۈش كېرەك››؛ ‹‹شىنجاڭنىڭ تېررورلۇققا قارشى تۇرۇش كۈرىشىنىڭ ئالاھىدىلىكىگە ماس كېلىدىغان زوراۋانلىق، تېررورلۇق جىنايى قىلمىشىغا قاقشاتقۇچ زەربە بېرىدىغان يەرلىك نىزام بەلگىلىمىلەرنى تۈزۈش كېرەك››... بۇ بىر قاتار تەكلىپلەر ئومۇمىيەتكە زىچ باغلانغان.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش ‹‹ئىجتىمائىي مۇقىملىق ۋە ئەبەدىي ئەمىنلىك››، ‹‹شىنجاڭنى قانۇن بويىچە ئىدارە قىلىش›› باش تېمىسىدىكى دائىمىي كومىتېت يىغىنى ئېچىپ، ئاپتونوم رايونلۇق پارتكومغا 14 پارچە تەكلىپ تاپشۇردى. ‹‹ئاپتونوم رايوننىڭ ئىتتىپاق، مۇقىم ۋەزىيىتىنى قەتئىي قوغداش توغرىسىدىكى قارار››نى چىقىرىپ، زوراۋانلىق، تېررورلۇق جىنايى ھەرىكەتلىرىگە قاقشاتقۇچ زەربە بېرىش، شىنجاڭنىڭ ئىجتىمائىي مۇقىملىقىنى قوغداش توغرىسىدا چاقىرىق چىقاردى... بۇ بىر قاتار ھەرىكەتلەر ئەمەلىيەتنىڭ سىنىقىدىن ئۆتتى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش مۇقىملىققا ئالاقىدار مۇھىم مەسىلىدە ئېنىق پوزىتسىيە بىلدۈردى. يېقىنقى يىللاردىن بۇيان ئاپتونوم رايونىمىزدىكى ھەر دەرىجىلىك سىياسىي كېڭەش تەشكىلاتلىرى ئوخشىمىغان شەكىلدە جەمئىي 5400 قېتىمدىن كۆپرەك سۆھبەت يىغىنى، لېكسىيە، شىكايەت يىغىنى ئېچىپ، ھەر مىللەت ئاممىنى مىللىي بۆلگۈنچىلىك ۋە دىن ئەسەبىيلىكى ئىدىيەسىنىڭ سىڭىپ كىرىشىگە قەتئىي قارشى تۇرۇشقا يېتەكلەپ ۋە تەربىيەلەپ، جەمئىيەتتىكى ھەر ساھەدىكىلەرنىڭ كۈچلۈك ئىنكاسىنى قوزغىدى.

    +

        شۇنىڭ بىلەن بىللە ھەر دەرىجىلىك سىياسىي كېڭەش تەشكىلاتلىرى ۋە سىياسىي كېڭەش ئەزالىرى ‹‹بەش ئاچقۇچ››تىن ئۇنىۋېرسال پايدىلىنىپ، توغرا ئېتىقاد ئارقىلىق سىقىپ چىقىرىش، مەدەنىيەت ئارقىلىق سۇسلاشتۇرۇش، قانۇن ئىدارە قىلىش ئارقىلىق چەكلەش، پەننى ئومۇملاشتۇرۇشتىن ئىبارەت ‹‹تۆتنى تەڭ باشقۇرۇش››تا چىڭ تۇرۇپ، ‹‹لېكسىيە ئۆمىكى››، ‹‹تەشۋىقاتچى››لارنىڭ رولىدىن تولۇق پايدىلىنىپ، دىن ئەسەبىيلىكى ئىدىيەسىنىڭ زىيىنىنى كەڭ تەشۋىق قىلىپ، ئاساسىي ئېقىم ئاۋازىنى ئاساسىي قاتلامغا يەتكۈزۈپ، كىشىلەرنى ياخشى تەربىيەلەپ، قەلبلەرنى تەسىرلەندۈرۈپ، ‹‹ئەسەبىيلىكنى تۈگىتىش››نى ئىلگىرى سۈرۈش داۋامىدا سىياسىي كېڭەش بىرلىك سېپىنىڭ ئاممىۋى خىزمەتتىكى ئەۋزەللىكى ۋە رولىنى جارى قىلدۇردى.

    +

        ماھىرلىق بىلەن ئىزدىنىپ، دادىل ئەمەلىيەتتىن ئۆتكۈزۈپ، ئەمەلىي ئۈنۈمگە ئەھمىيەت بېرىپ، كېڭىشىش شەكلىدە يېڭىلىق يارىتىش

    +

        23 – مارت چۈشتىن بۇرۇن ئاپتونوم رايونلۇق سىياسىي كېڭەش بىر مەيدان قىزغىن سۆھبەت يىغىنى ئۆتكۈزدى. يىغىنغا قاتناشقان سىياسىي كېڭەش ئەزالىرى، مۇتەخەسسىسلەر، يەتتە فۇنكسىيەلىك تارماق ۋە بىر قىسىم ئاساسىي قاتلام سىياسىي كېڭەشنىڭ مەسئۇللىرى ‹‹ئەنئەنىۋى يېزا – قىشلاقلارنى قوغداش›› دېگەن تېمىنى چۆرىدەپ بەس – بەستە پىكىر بايان قىلدى. بۇ ئاپتونوم رايونلۇق سىياسىي كېڭەش 2014 – يىلى ئايلىق كېڭىشىش سۆھبەت يىغىنى ئۆتكۈزۈشنى يولغا قويغاندىن بۇيان ئۆتكۈزۈلگەن 19 – قېتىملىق ئايلىق كېڭىشىش سۆھبەت يىغىنى.

    +

        يېقىنقى يىللاردىن بۇيان ئاپتونوم رايونلۇق سىياسىي كېڭەش دىققەتنى ‹‹تۆت ئومۇميۈزلۈك›› ئىستراتېگىيەلىك ئورۇنلاشتۇرمىسىغا مەركەزلەشتۈرۈپ، ئاپتونوم رايوننىڭ مۇھىم تەدبىر ئورۇنلاشتۇرمىسىنى ئەمەلىيلەشتۈرۈشكە تۈرتكە بولۇشنى چۆرىدەپ، كېڭىشىش پائالىيىتىنىڭ ئۈنۈملۈك شەكلى ئۈستىدە پائال ئىزدىنىپ، پارتىيە، ھۆكۈمەت تارماقلىرى بىلەن بولغان خىزمەت ئالاقىسى تۈزۈمىنى يەنىمۇ مۇكەممەللەشتۈرۈپ، ئوخشىمىغان شەكىلدە مەخسۇس كېڭىشىش، نىشانلىق كېڭىشىش، ساھەلەر بويىچە كېڭىشىش، تەكلىپ بېجىرىش ئەھۋالى بويىچە كېڭىشىشنى قانات يايدۇرۇپ، كېڭىشىش ئۈنۈمىنى يەنىمۇ ئاشۇردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش 2014 – يىلىدىن باشلاپ سىياسىي كېڭەشنىڭ كېڭىشىش ئاساسىدىكى دېموكراتىيە قەدىمىنى ئۈزلۈكسىز تېزلىتىش ئۈستىدە ئىزدىنىپ ۋە ئۇنى كېڭەيتىپ، ئاپتونوم رايونلۇق پارتكوم ۋە جەمئىيەتتىكى ھەر ساھەنىڭ يۈكسەك دىققىتىنى قوزغىدى ۋە تولۇق مۇئەييەنلەشتۈرۈشىگە ئېرىشتى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش ‹‹ئىسلاھاتنى ئومۇميۈزلۈك چوڭقۇرلاشتۇرۇش››نى باش تېما قىلىپ، سىياسىي كېڭەش ئاپتونوم رايونلۇق 11 – نۆۋەتلىك كومىتېتىنىڭ 7 – قېتىملىق دائىمىي كومىتېت يىغىنىنى ئېچىپ، مەمۇرىيەت ئىشلىرىنى مەخسۇس كېڭىشىپ، يىپەك يولى ئىقتىساد بەلبېغى يادرولۇق رايونى قۇرۇش، مەمۇرىي تەستىق تۈزۈمى ئىسلاھاتىنى چوڭقۇرلاشتۇرۇش قاتارلىق يەتتە تەكلىپ لايىھەسىنى شەكىللەندۈرۈپ، ئىسلاھاتنى ئىلگىرى سۈرۈشتىكى تەدبىر بەلگىلەشكە مەسلىھەت بېرىش رولىنى جارى قىلدۇردى؛ ‹‹شىنجاڭنى قانۇن بويىچە ئىدارە قىلىش››نى باش تېما قىلىپ، سىياسىي كېڭەش ئاپتونوم رايونلۇق 11 – نۆۋەتلىك كومىتېتىنىڭ 10 – قېتىملىق دائىمىي كومىتېت يىغىنىنى ئېچىپ، مەمۇرىيەت ئىشلىرىنى مەخسۇس كېڭىشىپ، قانۇن ئىدارە قىلىدىغان شىنجاڭ قۇرۇش ئۈچۈن ئەقىل كۆرسەتتى؛ تەڭرىتاغ 1 – مۇزلۇقى تەبىئىي مۇھاپىزەت رايونى قۇرۇشنى مەخسۇس كېڭىشىپ، دېموكراتىك نازارەت قىلىش خىزمىتىنى كۈچەيتىش ئۈستىدە ئىزدەندى؛ ‹‹شىنجاڭدا ئىختىساسلىقلارنى تەرەققىي قىلدۇرۇش››نى باش تېما قىلىپ، سىياسىي كېڭەش ئاپتونوم رايونلۇق 11 – نۆۋەتلىك كومىتېتىنىڭ 11 – قېتىملىق دائىمىي كومىتېت يىغىنىنى ئېچىپ مەمۇرىيەت ئىشلىرىنى مەخسۇس كېڭىشىپ، ئاپتونوم رايونلۇق پارتكومنىڭ ‹‹ئىختىساسلىقلار ئارقىلىق ئاپتونوم رايوننى قۇدرەت تاپقۇزۇش›› ئىستراتېگىيەلىك ئورۇنلاشتۇرمىسىنى ئەمەلىي ھەرىكىتى ئارقىلىق ئەمەلىيلەشتۈردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش 2014 – يىلى تۇنجى قېتىم كېڭىشىش خىزمىتى يىللىق پىلانىنى تۈزدى، ئىككى يىلدىن بۇيان جەمئىي 26 تۈرلۈك كېڭىشىش پىلانىنى تۈزدى، ‹‹يىللىق كېڭىشىش پىلانىنى بېكىتىش ۋە ئەمەلىيلەشتۈرۈش توغرىسىدىكى ۋاقىتلىق يولغا قويۇش چارىسى››نى تۈزۈپ، ئاپتونوم رايونلۇق پارتكوم دائىمىي كومىتېتىنىڭ تەستىقلىشى ھەم تەشكىللەپ يولغا قويۇشىغا سۇنۇپ، سىياسىي كېڭەشنىڭ كېڭىشىش پائالىيىتىنى ئاپتونوم رايونلۇق پارتكومنىڭ ئورۇنلاشتۇرمىلىرىدا تېخىمۇ نامايان قىلىپ، تۈرلۈك كېڭىشىش پائالىيەتلىرىنى تېخىمۇ قېلىپلاشتۇردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش 2014 – يىلى 2 – ئايدا تۇنجى قېتىملىق ئايلىق كېڭىشىش سۆھبەت يىغىنى ئاچتى، ھازىرغىچە مىللىي تېبابەت دورىگەرلىكىنى راۋاجلاندۇرۇش، سانائەت رايونلىرىنىڭ ئېنېرگىيەنى تېجەپ، بۇلغىمىنى ئازايتىشنى چۆرىدىگەن ھالدا 19 قېتىملىق ئايلىق كېڭىشىش سۆھبەت يىغىنى ئاچتى، كېڭىشىش تېمىسىنىڭ كۆپىنچىسىدە ئومۇمىيەتكە مۇناسىۋەتلىك ‹‹كىچىك مەسىلىلەر››نى چىقىش قىلىپ ئوتتۇرىغا قويغان كېڭىشىش پىكىرلىرى پارتكوم، خەلق ھۆكۈمىتى تەرىپىدىن قوبۇل قىلىنىپ، مول نەتىجە بېرىپ، سىياسىي كېڭەش خىزمىتىنىڭ بىر چوڭ يارقىن نۇقتىسىغا ئايلاندى.

    +

        2016 – يىلى چاغان تۈگىشى بىلەنلا ئاپتونوم رايونلۇق سىياسىي كېڭەش ساياھەتچىلىكنى راۋاجلاندۇرۇشنى ئىلگىرى سۈرۈش نىشانلىق كېڭىشىش سۆھبەت يىغىنى، شىنجاڭنىڭ ئالاھىدە تىرانسفورموتور ئېلېكتىر تورى قۇرۇلۇشى ۋە ئېلېكتىر ئېنېرگىيە مەخسۇس كېڭىشىش سۆھبەت يىغىنىنى ئاچتى، بۇ ئاپتونوم رايونلۇق سىياسىي كېڭەش پارتگۇرۇپپىسىنىڭ يېڭى يىلدىكى يېڭى ھەرىكىتىدە يېڭىلىق ياراتقانلىقى، شۇنداقلا كېڭىشىش ئاساسىدىكى دېموكراتىيە شەكلىنى كېڭەيتىشتىكى مۇھىم ئۇسۇل بولۇپ، سىياسىي كېڭەشنىڭ كېڭىشىش ئاساسىدىكى دېموكراتىيە قۇرۇلۇشىنى ئىلگىرى سۈرۈشتە ئۈلگىلىك رول ئوينىدى.

    +

        پۈتۈن كۈچ بىلەن ئىشلەشكە ماھىر بولۇپ، تەرەققىياتنى كۆزلەپ ئىقتىسادىي، ئىجتىمائىي ئىشلارغا مۇلازىمەت قىلىش

    +

        ج ك پ مەركىزىي كومىتېتى سىياسىي بىيۇروسىنىڭ ئەزاسى، ئاپتونوم رايونلۇق پارتكومنىڭ شۇجىسى جاڭ چۈنشيەن 2014 – يىلىنىڭ ئاخىرىدا ‹‹شىنجاڭنى ئەڭ پاكىز جاي قىلىپ قۇرۇپ چىقىش››تەك ئېكولوگىيە مەدەنىيلىكى قۇرۇلۇشى تېمىسىنى تەنتەنىلىك ئوتتۇرىغا قويدى ھەم بۇ خىزمەتنى سىياسىي كېڭەشنىڭ مەسئۇل بولۇشىغا تاپشۇردى.

    +

        بىر يىلدىن كېيىن ‹‹پاكىز شىنجاڭ قۇرۇش›› ئىدىيەسى كىشىلەر قەلبىدىن ئورۇن ئالدى، شىنجاڭدىكى ھەر مىللەت خەلق پاكىز شىنجاڭ قۇرۇشقا قىزغىن ئاتلاندى، شىنجاڭنىڭ تاغلىرى تېخىمۇ يېشىللىققا پۈركەندى، سۈيى تېخىمۇ سۈزۈلدى، ھاۋاسى تېخىمۇ ساپلاشتى... ئاپتونوم رايونلۇق سىياسىي كېڭەش پاكىز شىنجاڭ قۇرۇش خىزمىتىنى چىڭ تۇتۇپ، تەڭرىتاغنىڭ جەنۇبى ۋە شىمالىغا يېشىللىق ئۇرۇقىنى چاچتى.

    +

        يېقىنقى يىللاردىن بۇيان ئاپتونوم رايونلۇق سىياسىي كېڭەش ‹‹تۆت ئومۇميۈزلۈك›› ئىستراتېگىيەلىك ئورۇنلاشتۇرمىسى بويىچە ئاپتونوم رايونلۇق پارتكوم ئورۇنلاشتۇرغان مەخسۇس خىزمەتلەرنى زىچ چۆرىدەپ، خەلق سىياسىي مەسلىھەت كېڭىشىنىڭ ئالاقە دائىرىسى كەڭ، ئىختىساسلىقلار توپلانغان بولۇشتەك ئەۋزەللىكىنى تىرىشىپ جارى قىلدۇرۇپ، پاكىز شىنجاڭ قۇرۇلۇشى، ئادەتتىن تاشقىرى نېفىت – گاز بايلىقىنى چارلاش – ئېچىش، خاس يېمەك – ئىچمەك كەسپىنى راۋاجلاندۇرۇش قاتارلىق خىزمەتلەردە مەسئۇلىيەتنى دادىل زىممىسىگە ئېلىپ، دادىل ئەمەلىيەتتىن ئۆتكۈزۈپ، تەشەببۇسكار بولۇپ، ئەقىل كۆرسىتىش سۈپىتىنى ئۆستۈرۈشكە كۈچەپ، سۆزى راست بولۇش، تەدبىرى ئەمەلىي بولۇش، ھەرىكىتى توغرا بولۇشنى ئىشقا ئاشۇرۇپ، سىياسىي كېڭەشنىڭ ياخشى ئاۋازىنى ياڭراتتى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش مەدەنىيەت، تارىخ ماتېرىيال خىزمىتىنى ئىلگىرى سۈرۈشتە يېڭىلىق يارىتىپ، ئاز سانلىق مىللەتلەرنىڭ 100 يىللىق ئەمەلىي خاتىرىسى، شىنجاڭنىڭ ‹‹ئۈچ ئەل›› پائالىيىتى ئەمەلىي خاتىرىسى، ياپون باسقۇنچىلىرىغا قارشى ئۇرۇش خاتىرىسى، غەربىي رايوننى كەڭ ئېچىش، ئەجدادلىرىمىز قاتارلىق تارىخىي ماتېرىياللارنى توپلاپ تۈزدى، بەزى نەشر بۇيۇملىرى ئېلىمىزنىڭ چېگرا مەدەنىيەت تارىخى كىتابلىرىنىڭ ئۈلگىسى بولدى، بەزىلىرى شىنجاڭنىڭ ياپون باسقۇنچىلىرىغا قارشى ئۇرۇش تارىخىي ماتېرىياللىرىدىكى بوشلۇقنى تولدۇرۇپ، سىياسىي كېڭەشنىڭ تارىخنى ئەستە تۇتۇپ، ئەلنى ئىدارە قىلىش، ئىتتىپاقلىشىش، ئادەم تەربىيەلەش فۇنكسىيەسىنى تولۇق جارى قىلدۇردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش يەنە ئىسلاھات، تەرەققىياتقا كۈچەش، خەلق تۇرمۇشىغا ئەھمىيەت بېرىش، شىنجاڭنى قانۇن بويىچە ئىدارە قىلىشتىكى ئىشلەش ۋە نەتىجە يارىتىشقا ئەھمىيەت بېرىپ، مەمۇرىيەت ئىشلىرىنى مەخسۇس كېڭىشىش ئارقىلىق ئىسلاھاتنى ئىلگىرى سۈرۈشتە تەدبىر بەلگىلەشتىن مەسلىھەت بېرىش رولىنى جارى قىلدۇردى ھەم ئاپتونوم رايونلۇق پارتكومنىڭ تۈرلۈك ئىستراتېگىيەلىك ئورۇنلاشتۇرمىلىرىنى ئەمەلىي ھەرىكىتى ئارقىلىق ئىزچىللاشتۇردى.

    +

        ئاپتونوم رايونلۇق سىياسىي كېڭەش ئامما كۆڭۈل بۆلىدىغان ئىشلارنى كۆڭلىگە پۈكۈپ، سىياسىي كېڭەشنىڭ خەلق ئۈچۈن كېڭىشىش، خەلقنى كۆزلەش، خەلق ئۈچۈن ئەقىل كۆرسىتىش، خەلق ئۈچۈن كۈچ قوشۇشىنى ئاڭلىق ئىشقا ئاشۇردى. يېقىنقى يىللاردىن بۇيان ئاپتونوم رايونلۇق پارتكومنىڭ ‹‹خەلق تۇرمۇشى ئەلا، ئامما بىرىنچى، ئاساسىي قاتلام مۇھىم›› تەلىپىنى ئەستايىدىل ئىزچىللاشتۇرۇپ، خەلق ئۈچۈن ۋەزىپىسىنى ئادا قىلىشتا چىڭ تۇرۇپ، ئىشقا ئورۇنلاشتۇرۇش، مائارىپ، داۋالاش، ئىجتىمائىي كاپالەت قاتارلىق ھەر مىللەت ئاممىنىڭ مەنپەئىتىگە مۇناسىۋەتلىك مەسىلىلەرنى زىچ چۆرىدەپ پائال ئەقىل كۆرسەتتى. قىز ئىستۇدېنتلارنى ئىشقا ئورۇنلاشتۇرۇش، كەسپىي مائارىپ ۋە كەسپىي تېخنىكا ماھارىتى بويىچە تەربىيەلەشنى كۈچەيتىش، ئۈرۈمچىنىڭ ئاتموسفېرا بۇلغىنىشىنى تىزگىنلەش، يېزىلاردىكى ئارتۇق ئەمگەكچىلەرنى يۆتكەشنى تېزلىتىش ۋە يېزا يۇقىرى ئۈنۈملۈك سۇ تېجەش قۇرۇلۇشى قاتارلىق قارالمىلارنى چوڭقۇر تەكشۈرۈپ تەتقىق قىلىپ، خەلق تۇرمۇشى قۇرۇلۇشىنى ئىلگىرى سۈرۈش ئۈچۈن ئەمەلىي تەدبىر كۆرسىتىپ، ئەمەلىيلەشتۈرۈشكە تۈرتكە بولدى. قىيىنچىلىقى بار ھەر مىللەت ئاممىنىڭ ئىشلەپچىقىرىش ۋە تۇرمۇشىغا كۆڭۈل بۆلۈپ ئوتتۇرىغا قويغان قوي، كالا گۆشى تولۇقلىمىسى بېرىش سالمىقىنى ئاشۇرۇش، چېگرا رايوندىكى ئاز سانلىق مىللەت رايونلىرىنىڭ ئەمىن تاپقۇزۇپ خەلقنى بېيىتىش، ئولتۇراقلاشتۇرۇپ چارۋىچىلىقنى گۈللەندۈرۈش قۇرۇلۇشى، چارۋىچىلارنىڭ يايلاق ھوقۇق – مەنپەئىتىنى قوغداشنى كۈچەيتىش جەھەتلەردىكى تەكلىپلىرىنىڭ ھەممىسى ئاپتونوم رايونلۇق پارتكوم تەرىپىدىن قوبۇل قىلىنىپ ئەمەلىيلەشتۈرۈلدى.

    +

        ھەر مىللەت، ھەر ساھە سىياسىي كېڭەش ئەزالىرى شىنجاڭنىڭ ئىقتىسادىي، ئىجتىمائىي ئىشلىرىدىكى خۇشاللىنارلىق ئۆزگىرىشلەرنى بىۋاسىتە كۆردى ۋە ئۇنىڭغا قاتناشتى، ئاپتونوم رايونلۇق سىياسىي كېڭەش ۋە سىياسىي كېڭەشكە قاتناشقان پارتىيە – گۇرۇھلار، تەشكىلاتلار، ھەر مىللەت، ھەر ساھە زاتلار شىنجاڭدىكى ھەر مىللەت خەلق بىلەن مۈرىنى – مۈرىگە تىرەپ ئىلگىرىلەپ، شانلىق نەتىجە ۋە شانلىق سەھىپە ياراتتى.

    +
    + +
    +

    ئەسكەرتىش:

    + تورىمىزدىكى ئەسەرلەرنىڭ نەشىر ھوقۇقى شىنجاڭ ئۇيغۇر ئاپتونوم رايونلۇق ئاخبارات ئىشخانىسىغا تەۋە، ھەرقايسى تاراتقۇلار كۆچۈرۈپ تارقاتقاندا «تەڭرىتاغ تورى›› دەپ مەنبەنى ئېنىق ئەسكەرتىشى كېرەك، بولمىسا قانۇنىي جاۋابكارلىقى سۈرۈشتە قىلىنىدۇ. +
    + +
    + + + + + + +
    + +
    +
    + + + + +
    + + +
    + +
    + +
    + + +
    + + + + + \ No newline at end of file diff --git a/test/testdata_uni2ascii/original_uy.txt b/test/testdata_uni2ascii/original_uy.txt new file mode 100644 index 0000000..3bf7f2c --- /dev/null +++ b/test/testdata_uni2ascii/original_uy.txt @@ -0,0 +1,2 @@ + + ئاپتونوم رايوننىڭ 2010–يىلىدىكى ئاپتونوم رايونلۇق پارتكوم سىياسىي كېڭەش خىزمىتى يىغىنىدىن بۇيانقى سىياسىي كېڭەش خىزمىتى توغرىسىدا ئومۇمىي بايان diff --git a/test/testdata_uni2ascii/qq_mail_https.txt b/test/testdata_uni2ascii/qq_mail_https.txt new file mode 100644 index 0000000..d6aca74 --- /dev/null +++ b/test/testdata_uni2ascii/qq_mail_https.txt @@ -0,0 +1,326 @@ +答复: weiyu - QQ邮箱
    答复: weiyu
    发件人:郑超 <littlefang@126.com>    
    时   间:2016年3月31日(星期四) 下午5:52纯文本 |
    收件人:
    test <testyouxiang2000@qq.com>

     

     

    发件人: 郑超 [mailto:littlefang@126.com]
    发送时间: 2016331 17:07
    收件人: 'monitor5210@sina.com' <monitor5210@sina.com>
    主题: weiyu

     

     ئاپتونوم رايوننىڭ 2010–يىلىدىكى ئاپتونوم رايونلۇق پارتكوم سىياسىي كېڭەش خىزمىتى يىغىنىدىن بۇيانقى سىياسىي كېڭەش خىزمىتى توغرىسىدا ئومۇمىي بايان

     

    +
    +يىلىدىكى + + diff --git a/test/testdata_uni2ascii/sina_read_mail.txt b/test/testdata_uni2ascii/sina_read_mail.txt new file mode 100644 index 0000000..fcbd9fe --- /dev/null +++ b/test/testdata_uni2ascii/sina_read_mail.txt @@ -0,0 +1 @@ +{"result":true,"errno":0,"msg":"","data":{"from":"testyouxiang2000@sohu.com","to":"\"testyouxiang2013\" ","cc":"","bcc":"","date":1459416272,"subject":"weiyu_fromsohu","priority":false,"notification_to":false,"xmsgid":"","isstar":false,"size":5778,"body":"

     <\/span><\/p>\n\n

    <\/span><\/span><\/span><\/span> \u0626\u0627\u067e\u062a\u0648\u0646\u0648\u0645 \u0631\u0627\u064a\u0648\u0646\u0646\u0649\u06ad\n2010\u2013\u064a\u0649\u0644\u0649\u062f\u0649\u0643\u0649 \u0626\u0627\u067e\u062a\u0648\u0646\u0648\u0645 \u0631\u0627\u064a\u0648\u0646\u0644\u06c7\u0642 \u067e\u0627\u0631\u062a\u0643\u0648\u0645 \u0633\u0649\u064a\u0627\u0633\u0649\u064a \u0643\u06d0\u06ad\u06d5\u0634 \u062e\u0649\u0632\u0645\u0649\u062a\u0649 \u064a\u0649\u063a\u0649\u0646\u0649\u062f\u0649\u0646 \u0628\u06c7\u064a\u0627\u0646\u0642\u0649\n\u0633\u0649\u064a\u0627\u0633\u0649\u064a \u0643\u06d0\u06ad\u06d5\u0634 \u062e\u0649\u0632\u0645\u0649\u062a\u0649 \u062a\u0648\u063a\u0631\u0649\u0633\u0649\u062f\u0627 \u0626\u0648\u0645\u06c7\u0645\u0649\u064a \u0628\u0627\u064a\u0627\u0646<\/strong><\/span><\/o:p><\/span><\/p>


    <\/strong><\/span><\/p>

    THIS THE END<\/strong><\/span><\/p>




    <\/a><\/div>\n


    ","ishtml":true,"attlist":[],"mid":"0468E2CEF23DB6E2F922C3916ACC53D99300000000000001","fid":"new","sendstatus":null,"neednotify":false}} \ No newline at end of file diff --git a/test/testdata_uni2ascii/sohu_mail_unicode.txt b/test/testdata_uni2ascii/sohu_mail_unicode.txt new file mode 100644 index 0000000..1b156ec --- /dev/null +++ b/test/testdata_uni2ascii/sohu_mail_unicode.txt @@ -0,0 +1 @@ +{"status": 1, "body": {"noconv": 0, "xtype": "", "encoding": 1, "type": 6, "charset": "", "force_charset": 0, "filename": "", "use_disp": 1, "subtype": "alternative", "length": 4040, "parts": [{"noconv": 0, "xtype": "", "encoding": 4, "type": 7, "charset": "", "force_charset": 0, "filename": "", "use_disp": 1, "subtype": "plain", "length": 564, "parts": "", "disposition": 0, "offset": 599, "form_name": "", "parameter": [["charset", "utf-8"]], "id": "", "d_filename": "", "description": ""}, {"noconv": 0, "xtype": "", "encoding": 4, "type": 7, "charset": "", "force_charset": 0, "filename": "", "use_disp": 1, "subtype": "html", "length": 3153, "parts": "", "disposition": 0, "offset": 1295, "form_name": "", "parameter": [["charset", "utf-8"]], "id": "", "d_filename": "", "description": ""}], "disposition": 0, "offset": 467, "form_name": "", "parameter": [["boundary", "----_=_NextPart_000_5b646341bfe7432f8237183bcf2e000e"]], "id": "", "d_filename": "", "description": ""}, "star": 0, "envelope": {"display_date": ["17:24", "3\u5206\u949f"], "cc": [], "references": [], "bcc": [], "subject": "weiyu_fromsohu", "from": [["", "testyouxiang2000@sohu.com"]], "from_after_1st_unread": [], "to": [["testyouxiang2013", "testyouxiang2013@sina.com"]], "userhdrs": [["X-Sohu-DeliverStatus", "<1459416272.ccab860401154443bf3d649ea1f67123.testyouxiang2000@sohu.com>"]], "message_id": "<1459416272.ccab860401154443bf3d649ea1f67123.testyouxiang2000@sohu.com>", "reply_to": [], "date": "Thu, 31 Mar 2016 17:24:32 +0800", "in_reply_to": [], "received": 0, "sender": [], "return_path": [], "mail_followup_to": [], "date_sent": 1459416272}, "maximum": "", "single": 1, "rowid": 478, "offset": 0, "path": "160331.8a5792b78519408ebc5c6966694f6557", "folder": 3, "size": 4507, "mailfrom": "testyouxiang2000@sohu.com", "name": "160331.8a5792b78519408ebc5c6966694f6557", "thread": 364, "mbox": 0, "have_forward": 0, "mid": "LMEQAAAANGZO37CWOMHAAAAAGIYDELRUGMXDCNBYFYYTMNTTDEAAAADUMVZXI6LPOV4GSYLOM4ZDAMBQIBZW62DVFZRW63LTE4AAAABRGYYDGMZRFY4GCNJXHEZGENZYGUYTSNBQHBSWEYZVMM3DSNRWGY4TIZRWGU2TO2IAAAAAA2M3CEAAA2IAAAAAA4YOAAAAA3LFONZWCZ3FF5ZGMYZYGIZHGEQAAAAHOZLJPF2V6ZTSN5WXG33IOUXGK3LM.2e987ff5eb62a18f10f1d758d6c9d00f", "display": "

     

    \n\n

     ئاپتونوم رايوننىڭ\n2010–يىلىدىكى ئاپتونوم رايونلۇق پارتكوم سىياسىي كېڭەش خىزمىتى يىغىنىدىن بۇيانقى\nسىياسىي كېڭەش خىزمىتى توغرىسىدا ئومۇمىي بايان


    THIS THE END






    \n


    ", "content": "\u0626\u0627\u067e\u062a\u0648\u0646\u0648\u0645 \u0631\u0627\u064a\u0648\u0646\u0646\u0649\u06ad 2010\u2013\u064a\u0649\u0644\u0649\u062f\u0649\u0643\u0649 \u0626\u0627\u067e\u062a\u0648\u0646\u0648\u0645 \u0631\u0627\u064a\u0648\u0646\u0644\u06c7\u0642 \u067e\u0627\u0631\u062a\u0643\u0648\u0645 \u0633\u0649\u064a\u0627\u0633\u0649\u064a \u0643\u06d0\u06ad\u06d5\u0634 \u062e\u0649\u0632\u0645\u0649\u062a\u0649 \u064a\u0649\u063a\u0649\u0646\u0649\u062f\u0649\u0646 \u0628\u06c7\u064a\u0627\u0646\u0642\u0649 \u0633\u0649", "attach": [], "have_read": 1, "memo": "", "have_reply": 0} \ No newline at end of file