├── README.md ├── 新浪微博数据 ├── microblogPCU.zip └── weibo_checker.py ├── Twitter └── twitter_account_checker.py └── Arxiv └── Arxiv.txt /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizhong2613/GraphAnomalyDetectionDatasets/HEAD/README.md -------------------------------------------------------------------------------- /新浪微博数据/microblogPCU.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lizhong2613/GraphAnomalyDetectionDatasets/HEAD/新浪微博数据/microblogPCU.zip -------------------------------------------------------------------------------- /Twitter/twitter_account_checker.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os.path 3 | import sys 4 | import urllib 5 | import urllib2 6 | 7 | import requests 8 | from joblib import Parallel, delayed 9 | 10 | from utils import read_file, append_list_to_csv 11 | 12 | 13 | class HeadRequest(urllib2.Request): 14 | def get_method(self): 15 | return "HEAD" 16 | 17 | 18 | getter = requests.Session() 19 | 20 | 21 | # keepalive_handler = HTTPHandler() 22 | # opener = urllib2.build_opener(keepalive_handler) 23 | # urllib2.install_opener(opener) 24 | 25 | 26 | def list_to_string(str_list, delimiter=","): 27 | return delimiter.join(map(str, str_list)) 28 | 29 | 30 | def two_dimensional_list_to_string(my_list): 31 | str_list = [] 32 | if isinstance(my_list[0], list): 33 | for row in my_list: 34 | str_list.append(list_to_string(row)) 35 | my_list = str_list 36 | return list_to_string(my_list, "\n") 37 | 38 | 39 | def get_webpage_source(url): 40 | page = urllib2.urlopen(url) 41 | return page.read() 42 | 43 | 44 | def get_webpage_final_url(url): 45 | # start = time.clock() 46 | failed = 0 47 | while failed < 4: 48 | try: 49 | page = getter.head(url, allow_redirects='true') 50 | # print time.clock() - start 51 | return page.url, page.status_code 52 | except requests.ConnectionError as e: 53 | print(e.message) 54 | print("Error, Try:" + str(failed) + " ,URL: " + url) 55 | return None, None 56 | 57 | 58 | def yql_url_builder(search_url): 59 | base_url = "http://query.yahooapis.com/v1/public/yql?q=" 60 | url_prefix = "&format=json&diagnostics=true" 61 | query = urllib.quote("select href from html where url=" + "'" + search_url + "'") 62 | return base_url + query + url_prefix 63 | # http://query.yahooapis.com/v1/public/yql?q=select%20href%20from%20html%20where%20url=%27http%3A//goo.gl/Q5EgIz%27&format=json&diagnostics=true 64 | 65 | 66 | def get_webpage_final_url_yql(url): 67 | query_result = get_webpage_source(yql_url_builder(url)) 68 | response = json.loads(query_result) 69 | if "redirect" not in response["query"]["diagnostics"]: 70 | return "" 71 | redirect_route = response["query"]["diagnostics"]["redirect"] 72 | if "content" not in redirect_route: 73 | return redirect_route[len(redirect_route) - 1]["content"] 74 | else: 75 | return redirect_route["content"] 76 | 77 | 78 | def append_to_file(data, path): 79 | f = open(path, 'a') 80 | f.write(data) 81 | f.close() 82 | 83 | 84 | def write_to_file(path, data): 85 | f = open(path, 'w') 86 | f.write(data) 87 | f.close() 88 | 89 | 90 | def append_url_record(response, result): 91 | if 'data' in response: 92 | response = (response['data'])[0] 93 | if len(result) == 0: 94 | result.append(response.keys()) 95 | result.append(response.values()) 96 | 97 | 98 | def read_csv(file_path): 99 | return [line.strip().split(",") for line in read_file(file_path)] 100 | 101 | 102 | def slice_csv(file_path): 103 | f = open(file_path, "rb") 104 | return set([line.strip().split(",")[0] for line in f]) 105 | 106 | 107 | def get_twitter_account_state(user_id): 108 | url = twitter_user_name_to_url(user_id) 109 | full_url = get_webpage_final_url(url[1]) 110 | if full_url[1] == 200: 111 | # print(url) 112 | if "suspended" in full_url[0]: 113 | print(url[0], "Fake") 114 | return url[0], "Fake" 115 | elif full_url[1] == 404: 116 | print(full_url, "Not Found") 117 | return url[0], "Not Found" 118 | else: 119 | print(url) 120 | # time.sleep(sleep_time + random.randint(0, 10)) 121 | 122 | 123 | def batch_url_extractor(input_path, output_path): 124 | last_id = False 125 | if os.path.isfile(output_path): 126 | last_id = get_last_written_id(output_path) 127 | f = read_file(input_path) 128 | for line_count, link in enumerate(f): 129 | user_id = link[0].strip() 130 | if last_id == user_id: 131 | last_id = False 132 | break 133 | if last_id is False: 134 | processes = Parallel(n_jobs=4)( 135 | delayed(get_twitter_account_state)(user_id) for user_id in f) 136 | processes = [x for x in processes if x is not None] 137 | # if line_count % 10000 == 0: 138 | append_list_to_csv(output_path, processes) 139 | # write_to_file(output_path, two_dimensional_list_to_string(result)) 140 | 141 | 142 | def twitter_user_name_to_url(username): 143 | return username, "https://twitter.com/" + username 144 | 145 | 146 | def get_last_written_id(file_path): 147 | for line in read_file(file_path): 148 | pass 149 | return line 150 | 151 | 152 | if __name__ == '__main__': 153 | print("start") 154 | batch_url_extractor("twitter_nodes.csv", "fake_users.txt") 155 | # if len(sys.argv) == 3: 156 | # batch_url_extractor(sys.argv[2], sys.argv[3], 0) 157 | # else: 158 | # print "Error: Please enter 2 parameters" 159 | """ 160 | if len(sys.argv) == 4: 161 | if sys.argv[1] == "facebook": 162 | batch_share_extractor(get_url_share_count, sys.argv[2], sys.argv[3], 3) 163 | elif sys.argv[1] == "twitter": 164 | batch_share_extractor(get_url_twitt_count, sys.argv[2], sys.argv[3], 3) 165 | else: 166 | print "Error: Please enter 3 parameters" 167 | """ 168 | print("finished") 169 | sys.exit(1) 170 | -------------------------------------------------------------------------------- /新浪微博数据/weibo_checker.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import urllib.request 4 | import json 5 | #from pymongo import MongoClient 6 | import pandas as pd 7 | 8 | import json 9 | import os.path 10 | import sys 11 | import urllib 12 | import time 13 | import numpy as np 14 | 15 | 16 | 17 | 18 | 19 | id = '1761179351' 20 | MONGO_HOST = 'mongodb://localhost:27017/weibo_database' # mongodb host path 21 | 22 | proxy_addr = "183.129.207.82:11031" 23 | fakeList =[] 24 | df1 = pd.DataFrame(columns=['id', 'name', 'profile_image_url','description','profile_url','verified','guanzhu','fensi','gender','urank','isAnomaly']) 25 | 26 | 27 | def use_proxy(url, proxy_addr): 28 | req = urllib.request.Request(url) 29 | req.add_header( 30 | "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0") 31 | proxy = urllib.request.ProxyHandler({'http': proxy_addr}) 32 | opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler) 33 | urllib.request.install_opener(opener) 34 | data = urllib.request.urlopen(req).read().decode('utf-8', 'ignore') 35 | return data 36 | 37 | 38 | def get_containerid(url): 39 | data = use_proxy(url, proxy_addr) 40 | content = json.loads(data).get('data') 41 | for data in content.get('tabsInfo').get('tabs'): 42 | if(data.get('tab_type') == 'weibo'): 43 | containerid = data.get('containerid') 44 | return containerid 45 | 46 | df1 = pd.DataFrame( 47 | columns=['id', 'name', 'profile_image_url', 'description', 'profile_url', 'verified', 'guanzhu', 'name', 48 | 'fensi', 'gender', 'urank','statusesCount','followersCount','followCount', 'isAnomaly'],index=np.arange(100000)) 49 | def get_userInfo(id,indexcount): 50 | global df1 51 | try: 52 | url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value='+id 53 | data = use_proxy(url, proxy_addr) 54 | content = json.loads(data).get('data') 55 | profile_image_url = content.get('userInfo').get('profile_image_url') 56 | description = content.get('userInfo').get('description') 57 | profile_url = content.get('userInfo').get('profile_url') 58 | verified = content.get('userInfo').get('verified') 59 | guanzhu = content.get('userInfo').get('follow_count') 60 | name = content.get('userInfo').get('screen_name') 61 | fensi = content.get('userInfo').get('followers_count') 62 | gender = content.get('userInfo').get('gender') 63 | urank = content.get('userInfo').get('urank') 64 | statusesCount = content.get('userInfo').get('statuses_count') 65 | followersCount = content.get('userInfo').get('followers_count') 66 | followCount = content.get('userInfo').get('follow_count') 67 | 68 | print("微博昵称:"+name+"\n"+"微博主页地址:"+profile_url+"\n"+"微博头像地址:"+profile_image_url+"\n"+"是否认证:"+str(verified)+"\n" + 69 | "微博说明:"+description+"\n"+"关注人数:"+str(guanzhu)+"\n"+"粉丝数:"+str(fensi)+"\n"+"性别:"+gender+"\n"+"微博等级:"+str(urank)+"\n") 70 | df1.iloc[indexcount] = {'id':id,'name':name,'profile_image_url':profile_image_url, 'description':description, 'profile_url':profile_url, 'verified':verified, 'guanzhu':guanzhu, 'name':name, 71 | 'fensi':fensi, 'gender':gender, 'urank':urank,'statusesCount':statusesCount,'followersCount':followersCount,'followCount':followCount, 'isAnomaly':0} 72 | 73 | # a = [id, name, profile_url, description, profile_url, str(verified), str(guanzhu), str(fensi), str(gender), str( 74 | # urank), str(0)] 75 | # df1.append(a) 76 | except : 77 | print(id +",Fake") 78 | df1.iloc[indexcount] ={'id': id, 'isAnomaly':1} 79 | 80 | # a=[id, "", "", "", "", str(""), str(""), str(""),str(""), str(""), str(1)] 81 | #df1.append(a) 82 | fakeList.append(id) 83 | return df1 84 | 85 | 86 | # 获取微博内容信息,并保存到文本中,内容包括:每条微博的内容、微博详情页面地址、点赞数、评论数、转发数等 87 | 88 | def get_weibo_store(id, file): 89 | i = 1 90 | while True: 91 | url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value='+id 92 | weibo_url = 'https://m.weibo.cn/api/container/getIndex?type=uid&value=' + \ 93 | id+'&containerid='+get_containerid(url)+'&page='+str(i) 94 | try: 95 | data = use_proxy(weibo_url, proxy_addr) 96 | print(data) 97 | content = json.loads(data).get('data') 98 | cards = content.get('cards') 99 | if(len(cards) > 0): 100 | 101 | for j in range(len(cards)): 102 | 103 | card_type = cards[j].get('card_type') 104 | if(card_type == 9): 105 | mblog = cards[j].get('mblog') 106 | attitudes_count = mblog.get('attitudes_count') 107 | comments_count = mblog.get('comments_count') 108 | created_at = mblog.get('created_at') 109 | reposts_count = mblog.get('reposts_count') 110 | scheme = cards[j].get('scheme') 111 | text = mblog.get('text') 112 | with open(file, 'a', encoding='utf-8') as fh: 113 | fh.write("----第"+str(i)+"页,第" + 114 | str(j)+"条微博----"+"\n") 115 | fh.write("微博地址:"+str(scheme)+"\n"+"发布时间:"+str(created_at)+"\n"+"微博内容:"+text+"\n"+"点赞数:"+str( 116 | attitudes_count)+"\n"+"评论数:"+str(comments_count)+"\n"+"转发数:"+str(reposts_count)+"\n") 117 | 118 | client = MongoClient(MONGO_HOST) # connect mongodb 119 | db = client.weibo_database # create db 120 | data_json = json.loads(data) # Decode the JSON from Twitter 121 | # insert the data into the mongodb into a collection 122 | db.chongbin_collection.insert(data_json) 123 | i += 1 124 | else: 125 | break 126 | except Exception as e: 127 | print(e) 128 | pass 129 | def read_file(path): 130 | with open(path, "r",encoding='ISO-8859-1') as f: 131 | for line in f: 132 | yield line 133 | 134 | 135 | def batch_url_extractor(input_path, output_path): 136 | 137 | #csv_data = pd.read_csv(input_path) 138 | 139 | f = read_file(input_path) 140 | for line_count, link in enumerate(f): 141 | if line_count== 0: 142 | continue 143 | if line_count == 100000: 144 | break 145 | if line_count % 1000 ==0: 146 | time.sleep(30) 147 | user_id = link.split(',')[0] 148 | print('当前用户:' + user_id) 149 | get_userInfo(user_id,line_count) 150 | time.sleep(3) 151 | df1.to_csv('./result_all_nodes2.csv',encoding='utf_8_sig') 152 | 153 | 154 | #get_userInfo('1402869242') 155 | #exit(0) 156 | if __name__ == '__main__': 157 | print("start") 158 | # 159 | 160 | batch_url_extractor("./all_nodes.csv", "fake_users.txt") 161 | exit(0) 162 | a = ['1041514813', '1372391882', '1465128481', '1576229144', '1705145357', '1752629790', '1757645411', '1816532795', 163 | '1830577063', '1838436697', '1876464221', '1908062085', '2064748387', '2128884541', '2346769694', '2425320194', 164 | '2459502185', '2617986623', '2641042505', '2643768800', '2696382082', '2766467333', '2768946311', '2784654125', 165 | '2786535687', '2833621377', '2891854953', '2899097081', '2998850183', '3031805374', '3072569041', '3073160087', 166 | '3087243885', '3089819133', '3118752457', '3147297283', '3152303751', '3152783674', '3175664544', '3184028954', 167 | '3225497724', '3254093841', '3254927351', '3307709485', '3308159265', '3317338860', '3391721524', '3427028600', 168 | '3429995494', '3508559184', '3591311671', '3723075335', '3723075914', '3723357835', '3764369327', '3817099196', 169 | '3914156316', '3972850415', '3973480557', '3975927245', '3978461117', '3978521513', '3978629730', '3983687100', 170 | '5035125768', '5043577095', '5063358893', '5071097702', '5087718785', '5103613401', '5118722930', '5135642220', 171 | '5138811486', '5151182890', '5161194256', '5208835275', '5212384562', '5237121924', '5245379166', '5291696737', 172 | '5293544530', '5305021616', '5322066783', '5323263294', '5324797585', '5325912225', '5326477957', '5328854844', 173 | '5331917298', '5331950652', '5332084382', '5335242471', '5361261043', '5365515981', '5365519449'] 174 | 175 | for item in a: 176 | time.sleep(3) 177 | get_userInfo(item) 178 | # if len(sys.argv) == 3: 179 | # batch_url_extractor(sys.argv[2], sys.argv[3], 0) 180 | # else: 181 | # print "Error: Please enter 2 parameters" 182 | """ 183 | if len(sys.argv) == 4: 184 | if sys.argv[1] == "facebook": 185 | batch_share_extractor(get_url_share_count, sys.argv[2], sys.argv[3], 3) 186 | elif sys.argv[1] == "twitter": 187 | batch_share_extractor(get_url_twitt_count, sys.argv[2], sys.argv[3], 3) 188 | else: 189 | print "Error: Please enter 3 parameters" 190 | """ 191 | print("finished") 192 | print(fakeList) 193 | sys.exit(1) 194 | -------------------------------------------------------------------------------- /Arxiv/Arxiv.txt: -------------------------------------------------------------------------------- 1 | 8 13 29 20 4 25 14 4 1 1 37 5 18 2 13 1 13 33 8 18 2 6 22 13 12 68 31 12 14 17 27 11 30 11 11 22 5 8 1 7 18 13 1 17 2 1 9 10 8 8 4 28 4 17 5 2 11 17 38 15 16 4 81 77 2 24 1 5 34 1 8 6 7 12 44 3 6 3 11 1 1 1 1 1 1 5 3 10 14 3 3 3 10 5 51 31 3 2 2 3 18 10 12 5 2 9 9 49 16 23 20 5 15 1 14 2 5 1 10 13 4 1 1 17 10 12 12 2 24 1 6 16 2 21 7 11 13 2 9 4 12 8 1 1 1 6 8 2 9 3 10 1 12 3 30 7 10 32 1 12 10 13 3 13 11 15 14 15 2 12 3 11 6 10 20 25 10 7 2 11 25 9 17 6 1 15 4 2 10 17 9 10 6 16 1 9 1 7 10 10 7 6 3 2 7 12 15 2 5 2 3 2 7 3 5 1 1 2 5 8 4 4 1 1 11 3 10 3 13 8 5 7 4 7 49 7 5 4 11 11 30 3 8 6 5 1 1 2 8 2 14 11 10 2 18 22 5 5 26 2 7 1 13 2 48 10 5 7 15 2 9 1 3 8 19 21 28 20 3 4 3 1 12 19 12 4 6 1 14 3 3 5 28 1 4 4 13 18 45 2 20 14 7 5 7 12 3 2 2 2 1 6 17 8 5 16 17 21 19 1 16 6 3 1 4 6 1 1 2 6 2 2 22 2 2 7 5 7 3 16 2 1 19 18 1 19 5 2 2 2 5 1 1 2 1 16 3 10 9 4 2 1 5 7 7 9 10 14 22 1 2 11 12 3 4 2 5 8 7 7 1 8 3 1 7 10 5 1 12 2 5 3 12 7 17 26 1 5 5 9 1 1 2 21 1 12 4 2 11 13 11 3 3 8 6 9 1 7 1 2 7 9 8 1 8 20 21 4 1 11 12 20 55 4 48 2 15 17 17 17 17 17 18 17 17 17 17 17 17 17 17 17 17 37 17 6 3 3 8 8 12 10 2 3 2 2 5 4 1 9 6 5 14 5 9 1 15 13 3 1 8 2 6 4 1 3 2 2 12 4 5 11 10 24 13 6 8 8 8 3 1 2 2 10 2 17 6 4 4 2 1 1 12 2 4 4 4 1 7 9 3 3 8 2 1 1 4 5 1 2 7 6 6 2 3 2 3 1 2 5 1 5 13 6 1 7 10 23 1 1 15 6 5 5 3 1 1 6 9 7 8 2 2 2 1 11 6 1 17 1 3 1 2 4 5 6 5 2 1 6 1 1 2 1 1 6 1 22 2 35 7 2 7 1 3 6 15 5 1 2 3 13 3 7 1 2 1 46 1 23 10 4 4 13 2 34 3 26 33 15 2 2 1 1 6 4 10 5 8 65 9 60 51 12 9 6 8 6 3 1 5 22 5 2 2 14 6 1 4 2 15 2 2 4 4 11 2 1 2 4 3 2 3 1 1 6 18 6 6 19 5 9 1 10 4 6 1 1 19 1 9 19 2 2 11 1 16 10 2 7 7 3 3 8 3 3 2 2 7 2 5 3 13 2 9 12 1 7 12 3 3 2 2 10 3 1 8 6 3 3 1 5 14 21 2 4 14 2 2 3 4 3 5 9 14 30 3 23 9 5 5 2 2 2 3 4 2 1 3 19 17 27 25 10 7 12 8 4 6 2 8 4 2 3 2 8 5 3 2 3 19 9 6 3 9 6 6 49 45 2 8 6 6 4 79 53 11 6 5 2 2 2 2 9 1 2 2 8 2 3 2 6 1 5 18 1 1 8 2 2 1 17 3 9 13 3 4 2 2 1 2 9 9 18 21 62 5 1 6 5 4 6 5 3 3 11 6 1 1 1 2 1 2 4 4 2 8 6 8 7 2 4 4 4 4 6 2 2 3 3 2 24 1 2 2 2 8 6 6 2 8 9 5 4 1 1 4 6 4 4 4 9 1 13 10 2 2 4 3 3 5 1 2 1 1 2 3 1 1 1 3 2 12 3 6 11 7 2 5 8 8 3 4 6 4 3 3 4 10 10 5 10 2 4 1 2 5 2 3 1 1 1 2 2 2 1 5 7 2 1 2 7 1 4 2 1 3 15 2 2 22 11 4 2 2 5 5 20 5 5 13 7 1 9 2 2 6 4 1 1 2 9 1 1 2 2 11 7 1 1 1 1 1 10 4 4 18 3 11 5 2 2 2 6 2 2 4 1 1 10 13 18 15 17 2 5 13 19 25 16 8 47 2 2 1 1 22 1 4 2 10 1 5 1 30 2 1 9 3 30 4 63 1 1 3 2 7 12 3 3 3 3 2 5 3 3 5 2 19 2 1 1 3 9 15 4 5 2 2 2 6 3 6 1 3 2 6 3 5 7 7 49 22 6 8 6 7 2 10 3 6 6 1 2 2 16 15 2 5 6 6 2 3 3 1 2 2 4 6 4 4 1 9 2 4 5 2 5 2 14 1 3 1 31 1 1 10 1 1 1 1 1 2 2 13 2 3 1 1 2 1 2 2 13 9 1 12 2 10 3 21 9 1 36 4 10 1 6 3 8 3 2 11 14 11 8 1 13 3 3 2 12 10 7 26 15 3 10 8 2 2 6 16 3 5 11 1 8 1 1 3 13 20 4 15 3 2 4 1 7 5 1 1 13 3 11 6 2 2 11 1 4 6 3 3 1 3 2 2 1 2 2 15 6 14 8 2 6 11 2 12 4 12 7 15 1 10 1 3 1 1 1 32 12 2 4 3 26 4 2 2 4 4 11 4 11 47 6 12 2 8 2 11 4 1 17 1 1 5 4 16 1 5 13 2 6 3 3 2 2 10 1 9 5 2 5 3 11 12 1 2 2 6 2 2 2 1 18 8 8 6 9 3 3 3 2 2 2 5 2 3 8 2 3 1 1 1 12 1 8 3 2 2 5 5 4 1 4 9 2 3 2 4 6 3 6 6 4 6 2 8 26 13 4 7 4 6 1 1 3 3 9 13 11 3 10 1 4 25 4 1 5 8 2 6 5 1 7 3 3 4 2 1 6 7 3 1 3 3 4 17 11 11 8 1 24 6 19 1 4 3 1 1 2 2 1 4 4 4 4 4 1 3 3 1 2 2 2 9 5 16 9 1 3 3 3 6 4 4 6 6 13 6 5 1 1 6 2 7 4 4 4 15 1 1 5 5 8 4 13 3 7 10 4 3 3 2 6 2 3 6 6 3 8 8 4 8 5 2 8 8 8 8 8 8 2 2 3 2 12 1 3 4 6 1 1 3 2 3 1 2 5 1 2 7 6 4 5 4 2 7 16 10 3 1 8 4 2 3 45 3 3 6 3 2 2 13 3 3 26 5 9 3 5 32 2 4 3 4 9 14 1 2 2 2 2 2 2 3 3 3 1 9 3 2 3 5 2 5 3 3 3 16 8 10 2 9 5 2 5 4 6 3 2 11 8 14 8 8 15 8 8 21 8 2 2 1 2 4 10 2 2 5 5 2 1 2 1 2 6 24 2 2 4 3 14 2 8 1 5 21 5 2 1 7 9 4 2 3 8 4 1 7 4 4 4 8 5 2 11 11 2 2 3 6 8 3 1 1 1 2 3 3 2 2 2 5 10 1 1 1 1 1 24 4 4 3 4 6 8 14 1 1 3 1 3 2 7 4 2 8 13 2 2 4 2 6 16 4 4 1 6 4 1 3 3 3 6 5 2 3 7 2 1 4 1 1 4 7 2 2 15 2 2 2 3 1 3 3 4 3 1 2 2 7 8 2 2 54 5 4 7 3 56 77 66 56 2 3 1 4 18 3 7 4 3 3 3 3 4 8 5 1 1 6 33 4 30 10 4 4 1 5 10 8 1 6 1 2 1 1 1 6 3 7 1 6 1 11 2 2 2 6 6 2 1 3 1 2 2 3 4 1 2 18 3 6 3 5 11 23 4 25 5 3 7 6 4 1 2 2 4 7 2 1 1 8 2 9 1 1 56 4 1 1 1 1 4 2 2 5 23 3 7 4 3 3 4 3 7 13 2 3 2 1 1 10 3 5 3 3 2 10 1 1 2 2 2 7 3 5 2 4 2 1 1 1 7 2 8 5 11 1 68 9 13 9 9 19 9 67 46 1 2 2 3 2 21 8 5 7 7 3 7 3 1 1 1 2 2 3 5 4 7 3 10 10 3 2 2 2 6 6 2 3 2 2 2 1 2 5 1 3 3 2 28 57 2 2 1 6 5 13 17 1 3 4 3 4 5 1 1 1 1 5 3 9 1 1 10 2 1 3 3 3 7 4 7 2 8 3 4 9 2 1 3 3 8 7 8 10 8 7 7 2 6 9 1 1 3 2 2 2 2 8 4 4 2 4 1 8 6 2 7 7 2 2 2 2 3 1 7 1 1 2 2 4 5 2 2 2 1 3 3 7 9 3 1 5 1 1 4 2 4 6 5 13 2 10 3 1 1 1 1 2 2 1 2 2 2 2 9 1 9 5 5 5 10 5 3 12 18 3 1 11 3 9 2 4 2 2 4 3 2 2 1 1 1 6 1 1 1 37 4 4 4 1 2 2 2 5 3 3 3 2 2 2 2 1 1 1 2 7 7 4 4 2 7 7 1 5 6 2 4 3 2 8 1 1 1 1 2 1 4 7 7 2 2 1 3 17 3 1 3 13 2 2 1 2 2 3 1 1 1 2 4 7 1 3 5 3 2 1 3 3 3 1 1 1 2 4 2 2 12 11 11 2 1 3 4 4 1 19 3 1 1 4 2 1 4 3 1 1 1 1 1 7 1 1 12 2 4 10 1 1 3 2 1 6 3 3 7 6 2 2 2 3 1 1 1 2 3 5 3 2 2 1 1 13 7 2 1 2 2 5 5 1 11 7 4 13 5 12 8 3 2 1 1 2 2 6 1 5 3 3 3 1 13 5 6 6 10 4 9 10 1 5 6 2 3 3 4 1 5 2 4 4 1 2 1 6 3 4 2 3 3 3 3 1 3 3 6 47 6 4 4 4 2 2 5 1 1 6 3 4 4 4 1 20 3 3 1 4 3 3 8 2 1 1 2 7 2 2 8 2 6 4 3 2 2 2 2 6 2 8 6 3 16 10 2 1 5 4 3 4 3 8 2 3 3 5 1 1 2 3 3 3 1 3 1 6 5 4 1 1 1 6 7 6 2 4 2 5 3 1 11 3 4 7 4 6 1 1 1 2 1 10 3 1 1 4 2 4 2 1 1 16 2 4 2 2 1 1 2 5 1 5 18 4 2 6 4 5 1 2 3 1 9 2 1 1 5 4 3 1 3 3 2 2 1 1 5 1 1 2 4 1 1 3 4 2 5 3 9 13 2 1 1 1 1 5 2 1 7 2 1 3 2 2 4 1 3 8 3 3 8 30 1 3 3 3 2 2 36 2 2 3 2 5 1 2 5 3 2 5 4 1 1 2 7 42 45 45 45 45 45 48 45 45 45 45 45 47 2 4 4 2 3 4 2 2 2 8 1 1 6 2 2 2 4 2 1 1 4 4 1 1 3 3 7 3 2 1 9 1 4 5 2 2 7 2 3 6 2 1 2 7 3 3 4 9 3 1 1 5 6 2 15 4 1 29 3 3 1 1 2 2 2 1 1 2 2 2 3 1 4 2 2 2 1 4 5 1 27 5 2 3 7 5 1 1 8 3 3 3 2 3 3 4 5 3 3 1 1 6 43 4 2 1 1 4 10 10 4 2 5 1 1 3 3 3 10 10 3 2 6 1 1 8 8 7 3 6 7 3 3 8 2 1 3 4 1 2 2 2 6 6 6 10 6 6 6 11 5 9 3 11 4 9 7 9 7 7 10 7 3 5 1 3 2 2 1 2 1 4 1 8 5 3 2 4 2 1 3 1 4 3 1 2 2 2 1 6 7 3 3 5 1 1 8 3 1 1 2 4 3 3 4 5 7 4 4 4 4 2 4 7 6 6 8 4 3 3 3 1 9 8 1 1 8 2 2 12 4 14 4 4 1 2 5 2 5 3 3 3 5 2 2 1 6 3 3 4 2 1 1 5 1 1 2 2 3 3 7 2 37 1 22 2 2 3 5 5 3 3 3 5 4 3 1 1 1 5 8 1 5 1 10 2 4 5 3 3 2 1 1 8 4 3 8 1 2 2 4 1 5 8 5 4 1 1 2 2 2 3 7 1 4 1 5 2 3 1 1 4 3 2 1 3 4 5 14 14 14 14 14 14 14 14 14 14 14 14 14 5 2 1 2 4 3 2 6 6 6 6 13 3 2 4 3 2 2 1 1 1 1 5 1 1 3 8 8 1 1 2 7 8 3 10 2 2 7 15 2 6 2 4 4 1 2 3 4 10 2 1 1 4 2 2 2 2 5 2 2 1 2 7 10 3 4 2 1 2 1 1 2 2 3 2 1 1 8 4 1 1 4 1 1 1 1 4 4 5 1 3 3 20 20 20 20 20 20 20 23 20 20 20 20 20 20 20 20 20 20 3 6 3 3 1 11 1 3 1 2 1 1 1 3 1 3 1 3 2 4 5 3 1 3 7 7 2 4 34 3 2 4 1 28 5 5 1 5 1 2 1 4 4 2 2 2 2 1 2 1 6 4 1 1 4 3 3 3 1 2 3 3 3 3 4 18 5 5 2 2 2 8 3 4 4 16 3 6 1 1 1 12 2 3 1 1 5 8 3 2 1 3 3 4 4 4 5 5 5 1 2 3 2 3 6 1 1 2 3 3 3 3 3 1 4 8 5 3 1 3 3 3 3 3 2 3 2 2 2 4 6 6 2 2 6 1 2 3 2 2 2 2 1 2 1 1 2 1 7 2 1 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 7 3 3 4 3 1 2 2 2 3 6 6 6 6 7 1 2 1 1 1 5 3 3 6 3 3 1 10 5 3 5 2 2 2 1 1 1 3 1 1 1 3 5 1 1 1 3 2 1 1 10 3 3 3 7 1 2 2 3 1 3 6 2 1 7 5 5 5 3 6 2 2 3 3 1 1 2 3 1 7 3 7 7 11 10 1 1 1 8 3 1 3 1 1 1 13 4 1 6 1 3 4 4 4 4 2 2 4 1 1 2 6 2 1 1 8 1 5 6 2 2 1 1 1 1 3 1 2 4 2 2 3 1 2 6 2 3 1 2 2 5 2 1 3 2 2 1 1 59 3 40 1 2 3 12 1 2 1 3 1 1 2 2 2 1 1 6 3 4 2 6 3 4 3 4 5 3 1 3 4 4 4 1 5 4 1 2 1 1 2 2 3 1 1 1 3 8 4 3 2 7 1 2 2 3 1 2 2 2 1 1 3 2 2 6 17 17 22 17 17 17 17 17 17 3 1 3 2 7 1 5 8 9 2 2 1 1 7 3 3 3 2 1 2 7 4 4 4 9 4 7 2 2 2 5 1 3 1 1 2 1 1 1 2 4 2 3 3 4 2 2 1 1 2 4 2 1 1 8 1 5 3 6 6 4 4 3 3 5 5 4 3 3 1 1 18 1 1 5 2 5 1 4 2 1 1 1 10 2 3 4 2 3 1 1 1 1 1 3 2 2 3 3 3 1 2 2 2 2 2 4 5 4 2 3 1 5 12 2 2 2 2 4 4 4 4 4 3 3 2 2 3 1 1 2 7 3 5 4 3 5 1 6 4 3 3 1 1 1 4 4 2 2 2 1 6 4 2 3 3 5 7 3 3 4 1 4 1 1 1 2 2 3 3 1 1 1 2 4 3 3 3 9 1 1 1 2 1 4 1 2 2 2 5 3 1 1 2 2 5 1 1 1 1 1 3 2 1 7 2 2 2 4 7 9 6 2 2 4 4 1 1 3 3 5 3 2 2 1 3 3 3 9 3 3 3 4 2 4 2 1 2 1 18 10 3 4 4 4 5 1 1 1 5 1 1 1 1 4 4 4 2 6 1 1 6 3 6 2 2 3 1 2 2 2 3 3 3 3 2 2 4 4 1 1 1 10 3 2 4 2 4 3 4 2 2 2 3 4 2 2 1 2 2 1 3 1 4 2 2 1 1 1 1 1 1 1 29 1 3 5 4 5 2 2 6 1 2 2 2 2 2 4 2 2 4 2 5 3 4 4 1 2 2 2 3 2 1 1 1 1 1 1 2 2 2 2 1 2 1 1 1 5 4 5 1 5 3 2 9 1 3 4 4 4 4 4 4 4 1 1 3 1 2 1 1 3 2 2 31 21 20 25 1 7 4 4 4 4 4 4 4 4 4 4 2 3 2 1 3 4 6 3 4 2 2 2 2 5 2 1 1 5 1 5 3 2 42 42 42 42 42 42 42 33 34 42 42 42 33 42 41 43 42 33 42 33 34 41 42 42 42 33 42 42 41 33 1 1 2 1 4 5 6 2 3 1 1 1 1 1 3 1 1 1 1 1 2 1 3 1 15 14 11 1 1 1 1 4 4 4 4 5 2 2 3 3 3 6 1 1 10 2 2 3 3 3 2 2 2 2 1 3 3 3 1 2 2 4 2 1 3 1 2 2 2 3 1 2 23 24 3 3 3 3 3 4 3 5 4 2 7 1 3 1 2 2 3 3 3 3 2 1 6 6 1 1 6 1 1 5 3 4 1 11 5 5 5 1 2 1 3 3 2 1 2 3 3 1 2 2 2 1 3 4 2 3 1 5 2 4 1 5 4 2 5 4 4 5 2 2 3 2 2 2 2 4 2 5 1 5 2 3 3 4 1 3 1 3 2 2 5 1 3 1 1 2 3 3 1 1 2 1 1 2 2 2 3 1 7 3 4 4 4 4 4 4 1 1 1 1 1 5 1 3 3 2 1 1 4 1 3 2 1 1 2 2 2 2 2 1 1 2 1 2 2 2 2 1 3 5 2 1 1 1 1 1 3 1 1 1 2 1 1 1 2 4 2 2 2 3 6 2 3 3 6 5 2 2 2 5 3 2 2 2 1 1 2 1 2 6 6 9 9 4 4 1 1 4 4 4 3 1 2 2 4 2 2 3 2 3 3 3 2 3 2 7 1 3 8 4 1 1 3 3 31 31 31 31 31 1 1 1 3 3 3 3 1 10 1 2 2 2 2 1 1 2 2 5 2 6 5 1 1 2 1 1 2 4 1 1 1 2 2 16 16 10 10 16 16 10 10 10 16 1 1 1 1 5 5 1 1 1 3 3 2 1 4 1 1 3 5 5 4 3 1 5 1 2 7 2 2 5 3 3 2 2 2 5 2 2 1 1 3 1 4 4 4 4 1 1 1 2 4 3 3 1 13 2 1 1 5 5 23 23 23 19 23 23 23 23 23 23 23 23 23 19 23 4 1 9 9 14 9 9 9 10 9 9 3 4 1 1 1 10 3 3 7 5 5 3 5 2 5 6 1 2 2 2 1 1 1 1 1 1 3 3 2 2 2 1 1 3 4 7 1 3 2 2 4 2 2 1 1 2 2 2 4 5 4 1 2 2 2 2 3 1 7 7 4 2 3 3 1 1 1 2 2 1 3 1 1 1 1 2 1 2 3 3 2 14 7 7 2 2 2 12 15 1 2 2 6 1 1 21 21 21 21 1 1 1 2 1 1 1 1 1 2 2 2 7 19 9 3 5 1 1 1 3 3 4 2 2 2 3 3 3 3 3 2 1 1 4 4 3 1 1 1 2 1 1 1 2 2 1 1 2 4 2 2 2 2 5 1 1 1 2 2 2 3 3 2 9 9 9 9 9 9 1 4 4 4 3 1 1 3 3 1 1 2 3 3 3 3 3 1 15 15 1 1 2 3 1 1 1 1 34 34 34 34 34 34 2 2 1 2 1 1 3 4 1 4 6 4 4 6 4 1 2 2 2 1 2 2 1 2 2 2 2 3 4 4 2 2 4 5 3 1 2 2 2 1 4 1 2 4 4 1 1 4 3 3 3 1 1 3 3 3 3 1 1 5 3 6 6 3 5 5 5 3 2 2 1 3 3 3 1 1 1 4 3 1 2 1 1 3 4 1 7 7 7 7 4 6 2 2 1 3 3 4 4 3 1 1 1 1 1 1 1 3 13 13 13 13 13 13 13 13 13 2 2 1 1 1 2 2 1 1 1 1 1 1 1 2 2 3 1 3 1 1 1 1 1 1 3 1 2 2 2 2 1 4 3 2 3 4 2 2 2 1 1 1 2 2 2 2 2 3 5 3 3 1 1 3 3 2 3 4 2 2 1 2 1 1 4 2 1 5 3 3 3 1 1 1 1 3 2 2 1 3 3 6 6 4 4 1 2 3 4 5 3 3 2 2 3 3 3 2 1 4 4 3 4 3 37 3 1 2 2 1 2 2 2 2 2 2 1 1 3 3 1 1 3 1 1 2 6 2 1 1 1 4 8 4 4 1 1 2 1 2 2 3 1 3 1 1 1 3 3 3 2 3 1 1 2 3 2 2 3 4 1 1 1 3 3 3 34 1 5 5 5 5 5 5 8 4 2 2 3 1 3 1 2 4 1 1 2 2 2 2 3 3 3 2 6 4 2 2 3 2 3 3 3 1 1 1 15 11 15 3 3 1 1 1 3 3 3 1 3 1 3 2 1 1 8 1 1 1 3 1 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 34 2 2 2 2 1 2 1 2 2 1 1 2 2 2 2 4 3 3 1 1 2 1 2 2 1 1 1 3 2 2 1 1 1 3 2 2 2 1 2 1 1 1 2 2 2 1 2 3 2 2 2 5 4 1 1 1 2 1 4 4 1 5 5 3 1 5 1 1 3 3 6 1 1 1 2 2 1 1 1 6 1 1 2 3 1 2 7 1 6 6 6 1 2 2 2 2 1 3 3 4 3 2 4 3 2 1 1 1 3 2 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 2 1 1 2 2 2 2 2 1 1 2 2 2 4 4 4 2 1 1 2 2 1 1 1 1 1 1 2 1 1 2 3 1 2 2 2 2 2 1 7 7 7 1 2 1 1 1 15 11 11 11 1 3 2 2 2 2 3 3 2 5 4 4 4 4 4 2 3 4 4 4 4 3 2 1 1 1 2 2 1 1 1 1 1 2 2 2 1 2 2 2 1 4 4 4 4 9 9 9 9 9 11 11 11 11 11 1 1 2 2 1 3 1 1 1 1 2 1 8 3 2 1 2 2 1 1 1 2 3 1 5 2 1 4 6 8 3 3 2 2 2 2 2 2 1 1 1 1 2 6 1 3 4 1 3 3 1 1 2 1 1 1 2 2 1 3 3 3 1 1 1 1 3 2 2 3 1 1 3 1 2 2 1 1 2 2 4 4 4 1 1 1 3 1 1 1 1 1 8 8 8 8 8 8 1 1 2 2 2 2 1 3 1 1 1 4 1 3 2 2 1 1 1 5 5 5 5 5 5 1 1 1 1 3 1 4 4 3 1 1 1 2 2 1 3 3 3 3 1 2 4 4 1 1 2 4 4 2 2 4 4 4 1 3 3 3 2 4 4 1 1 3 4 4 1 1 3 3 2 2 3 2 3 3 2 6 4 2 2 3 1 1 2 2 2 2 2 2 2 2 4 4 4 6 6 6 6 1 1 8 2 3 1 3 1 1 1 4 4 1 1 3 1 2 3 3 3 2 2 3 2 1 2 2 1 1 1 1 2 2 2 3 3 3 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 1 1 2 2 3 --------------------------------------------------------------------------------