-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path16.py
executable file
·395 lines (368 loc) · 22.5 KB
/
16.py
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
#!/usr/bin/env python3
import re
from collections import namedtuple, defaultdict
# HELPER FUNCTIONS
Rule = namedtuple('Rule', 's1 e1 s2 e2 name')
Model = namedtuple('Model', 'rules tickets yours')
def parser(text) -> Model:
split = text.split('nearby tickets:')
constraints = re.findall(r'(.*): (\d+)-(\d+) or (\d+)-(\d+)', split[0])
tickets = [tuple(map(int, l.split(','))) for l in split[1].strip().split('\n')]
constraints = [Rule(int(s1), int(e1), int(s2), int(e2), name) for name, s1, e1, s2, e2 in constraints]
yours = tuple(map(int, split[0].split('your ticket:')[1].split(',')))
return Model(constraints, tickets, yours)
def read_input() -> str:
with open(__file__, encoding="utf-8") as f:
c = f.read()
data = c[c.rindex("🎅") + 1: c.rindex("⛄")].rstrip()
return data
# MAIN FUNCTIONS
def find_invalid_tickets(m):
not_in = set()
for rule in m.rules:
not_in.update(range(rule[0], rule[1] + 1))
not_in.update(range(rule[2], rule[3] + 1))
non_valid = [(v, i) for i, t in enumerate(m.tickets)
for v in t if v not in not_in]
return non_valid
def part1(m: Model) -> int:
non_valid = find_invalid_tickets(m)
return sum(v for v, _ in non_valid)
def part2(m: Model, begin: str = 'departure') -> int:
validator = {rule.name: (range(rule[0], rule[1] + 1), range(rule[2], rule[3] + 1)) for rule in m.rules}
tickets = m.tickets
invalid = {i for _, i in find_invalid_tickets(m)}
tickets = [t for i, t in enumerate(tickets) if i not in invalid]
helper = defaultdict(set)
for i in range(len(m.tickets[0])):
vals = {t[i] for t in tickets}
for name in validator.keys():
interval1, interval2, all_accept = validator[name][0], validator[name][1], True
for field in vals:
all_accept = all_accept and field in interval1 or field in interval2
if not all_accept:
break
if all_accept:
helper[name].add(i)
# sort by set length
helper = {k: v for k, v in sorted(helper.items(), key=lambda item: item[1])}
identifier, occupied = dict(), set()
for k, v in helper.items():
v -= occupied
if len(v) == 1:
index = next(iter(v))
identifier[k] = index
occupied.add(index)
my_ticket, res = m.yours, 1
for name in validator.keys():
if name.startswith(begin):
res *= my_ticket[identifier[name]]
return res
# TEST
def test() -> bool:
# GIVEN
given = parser("""
class: 1-3 or 5-7
row: 6-11 or 33-44
seat: 13-40 or 45-50
your ticket:
7,1,14
nearby tickets:
7,3,47
40,4,50
55,2,20
38,6,12
""")
assert part1(given) == 71
# GIVEN
given = parser("""
class: 0-1 or 4-19
row: 0-5 or 8-19
seat: 0-13 or 16-19
your ticket:
11,12,13
nearby tickets:
3,9,18
15,1,5
5,14,9
""")
assert part2(given, '') == 11 * 12 * 13
return True
if __name__ == '__main__':
assert test()
model = parser(read_input())
# ONE #1
part_1 = part1(model)
print(part_1)
assert part_1 == 28884
# # TWO #2
part_2 = part2(model)
print(part_2)
# assert part_2 == 3443997590975
# INPUT
"""🎅
departure location: 49-258 or 268-960
departure station: 37-117 or 128-968
departure platform: 31-70 or 78-974
departure track: 26-234 or 247-952
departure date: 49-625 or 635-969
departure time: 26-777 or 799-974
arrival location: 49-735 or 757-971
arrival station: 28-381 or 399-970
arrival platform: 49-77 or 95-957
arrival track: 29-467 or 477-950
class: 40-218 or 234-967
duration: 45-900 or 911-970
price: 42-442 or 452-966
route: 45-104 or 112-953
row: 49-877 or 884-957
seat: 40-168 or 184-953
train: 43-913 or 920-949
type: 43-292 or 315-955
wagon: 48-547 or 558-954
zone: 40-929 or 935-954
your ticket:
59,101,191,149,167,197,199,137,163,131,113,67,103,97,61,139,157,151,193,53
nearby tickets:
765,721,63,432,949,277,838,143,894,681,976,948,949,605,810,368,595,729,593,373
205,877,327,644,328,652,102,892,156,525,884,355,195,187,106,886,405,608,163,286
602,284,250,271,156,561,113,376,892,554,800,328,924,526,321,434,368,837,59,491
923,604,129,647,801,838,620,152,50,673,804,54,371,354,687,877,983,334,723,566
569,870,114,688,613,521,368,501,857,480,406,927,402,125,429,357,217,651,463,821
513,147,329,113,856,734,867,495,381,728,400,661,843,583,857,820,925,323,532,931
70,274,713,453,195,776,379,337,221,899,139,286,866,139,888,562,776,777,651,460
857,861,499,561,335,690,333,890,935,807,333,64,843,531,405,424,945,668,445,279
758,590,983,582,770,543,250,601,766,151,55,420,651,498,327,861,857,319,530,372
872,286,949,708,466,279,613,719,485,404,590,273,283,842,644,599,340,873,203,266
773,152,616,449,415,414,875,617,114,281,66,644,602,639,694,671,203,638,97,840
945,731,834,455,304,199,808,524,829,421,437,648,339,408,65,341,258,836,714,285
65,94,429,586,835,408,565,186,682,674,947,329,332,365,279,573,695,198,458,887
812,525,554,765,807,642,574,661,842,713,559,100,329,715,640,198,766,801,681,820
164,358,106,428,286,518,334,440,845,139,134,402,289,570,813,234,341,114,945,189
135,332,99,857,814,280,216,114,414,441,501,137,66,677,172,833,402,254,617,52
569,836,312,136,185,809,54,206,493,724,426,509,257,257,493,358,426,406,688,701
188,715,655,892,603,478,253,526,423,904,315,166,279,894,249,853,327,351,533,442
438,912,675,840,462,816,595,399,761,653,825,820,858,769,426,146,671,150,124,435
944,559,642,233,652,429,819,492,196,361,292,252,372,114,134,935,771,674,623,871
150,699,279,604,665,866,698,424,535,827,401,111,767,207,923,414,581,568,201,868
462,67,479,164,763,690,759,491,638,620,605,687,201,537,80,913,833,559,209,509
188,326,700,150,648,845,435,103,714,510,733,595,635,768,304,843,104,710,486,101
760,578,172,465,453,726,622,724,536,852,616,828,723,493,139,128,193,940,929,523
156,251,280,661,851,526,596,621,731,980,868,575,774,699,913,516,362,492,216,773
844,638,563,605,130,320,360,322,359,648,599,890,497,0,274,497,719,563,462,949
564,619,482,684,485,848,347,62,562,695,898,486,436,402,610,279,849,278,928,235
70,495,404,863,161,541,988,573,940,434,358,862,673,698,255,284,652,465,483,55
893,160,425,13,948,210,604,656,138,584,865,695,61,147,352,771,652,770,704,133
189,278,635,864,559,140,849,578,514,234,718,117,601,53,835,485,828,496,55,557
658,147,128,143,864,666,682,167,675,827,153,272,288,621,443,704,890,766,332,53
416,164,370,825,845,976,697,693,921,801,920,693,767,876,488,527,614,439,114,893
467,944,689,572,153,592,943,520,385,693,456,542,559,890,615,373,712,334,361,723
862,325,622,215,639,95,59,194,128,605,328,453,876,271,324,572,602,652,598,225
615,491,867,818,670,894,830,642,461,802,639,621,117,455,998,348,402,325,587,418
357,463,582,669,203,528,819,234,528,606,289,138,210,815,480,674,601,279,266,536
353,896,515,477,658,418,482,287,202,757,442,222,924,669,537,593,55,155,523,625
134,201,689,502,424,499,97,58,525,513,65,202,211,648,832,987,695,571,944,659
185,651,380,686,626,612,635,512,461,143,437,343,897,370,70,686,850,814,503,766
456,615,589,491,592,669,578,484,827,402,539,158,275,281,775,404,227,357,667,714
816,522,729,608,160,137,625,857,748,65,113,199,211,857,607,836,569,892,204,564
515,126,804,159,573,810,814,496,599,611,361,134,584,535,337,893,945,479,62,719
645,509,576,461,517,430,611,542,692,339,666,729,351,677,368,835,299,500,406,597
576,241,112,576,252,131,730,136,657,433,813,831,378,214,376,481,710,154,188,349
585,942,712,291,563,143,877,592,925,571,68,350,110,591,269,357,870,759,441,595
465,481,67,912,433,673,292,758,827,695,203,362,860,710,616,940,273,477,22,764
509,270,939,711,406,461,921,409,568,824,365,167,613,408,732,841,886,19,770,658
114,690,806,273,942,900,103,278,588,153,686,423,801,548,650,702,893,440,66,731
142,671,458,871,925,945,594,377,193,361,139,497,160,865,163,688,96,723,945,996
327,655,833,623,374,829,509,157,732,535,887,644,258,271,873,112,141,428,780,558
765,466,52,204,174,667,803,826,712,672,759,816,943,142,717,168,927,353,505,409
340,626,895,248,685,288,137,837,335,204,889,714,407,330,143,151,51,861,854,112
771,891,403,537,571,193,863,624,73,811,272,515,660,432,510,570,617,606,456,663
489,102,195,709,205,431,821,586,98,569,349,431,504,807,51,255,543,676,506,73
762,939,856,734,352,524,855,413,725,400,573,704,759,832,666,187,502,594,632,703
836,611,137,674,777,283,506,100,289,255,191,822,364,273,625,902,218,216,500,189
884,354,440,584,681,638,570,211,846,285,776,248,488,994,318,810,421,685,523,504
942,897,617,157,808,857,929,584,869,143,493,501,433,816,467,167,318,420,418,447
665,928,366,707,369,272,692,876,661,58,504,647,643,638,563,457,849,450,566,726
523,164,570,516,854,68,400,234,929,848,705,871,854,184,949,4,505,860,660,524
288,855,636,814,616,132,206,662,734,425,149,540,807,336,671,980,640,58,702,759
900,770,567,250,779,187,644,835,370,863,871,256,761,494,133,714,205,578,516,942
271,899,374,845,125,440,216,716,132,612,643,608,414,730,323,820,329,851,348,254
900,621,332,651,713,320,375,284,489,924,341,812,570,560,393,519,820,372,503,113
519,622,875,402,662,158,846,128,347,669,50,78,491,766,876,615,56,253,490,483
344,415,487,216,244,430,478,761,841,374,500,851,332,769,287,137,54,52,701,199
337,859,147,190,876,609,315,706,729,583,12,625,356,566,723,142,196,148,200,187
662,831,599,379,617,912,322,410,437,67,859,152,564,85,332,271,153,572,714,709
380,73,563,541,269,677,487,69,132,598,758,692,526,510,808,806,423,723,410,535
218,206,377,622,209,515,595,130,546,981,680,142,189,168,943,52,896,848,706,205
143,653,861,384,497,277,522,345,568,247,911,426,427,592,61,490,456,571,53,286
489,576,925,414,912,607,691,769,57,801,480,139,636,380,145,270,362,133,109,642
614,513,155,200,437,400,353,700,57,825,697,929,671,895,455,585,901,805,52,851
656,619,396,759,842,454,60,569,536,593,806,810,621,579,606,218,351,613,815,163
58,407,726,354,683,273,318,167,291,285,524,550,807,759,651,434,144,361,405,349
839,494,767,615,579,845,460,129,282,920,690,490,671,452,581,514,726,11,186,648
58,505,612,340,591,692,457,268,536,528,676,664,2,405,152,477,614,465,729,896
184,321,841,10,871,854,317,894,804,356,288,64,102,831,616,191,866,830,103,374
270,944,576,872,248,868,891,319,399,159,612,887,60,228,586,835,290,258,99,717
768,107,946,477,284,545,505,194,485,713,273,156,844,428,441,290,202,925,666,453
447,540,377,838,190,66,151,828,589,195,531,943,317,654,817,524,248,898,536,771
836,62,947,164,573,145,129,624,412,511,139,682,421,659,548,723,341,545,807,826
130,483,144,653,659,568,766,288,200,441,681,502,829,104,628,702,667,594,537,816
164,378,867,888,193,535,475,374,680,886,531,653,813,348,355,519,281,317,598,858
870,545,920,255,146,735,912,324,92,187,814,807,562,316,362,255,920,442,694,895
336,134,333,946,666,823,401,481,51,867,578,499,135,378,863,112,771,189,358,83
833,319,649,440,503,403,184,453,638,695,368,337,482,893,810,112,433,52,555,579
167,687,362,982,526,698,364,350,359,565,103,420,399,503,656,327,502,711,479,672
509,764,893,596,152,217,270,347,380,729,821,612,583,277,209,56,675,683,380,314
733,153,491,585,871,458,674,66,714,849,157,97,407,473,425,720,937,421,771,616
517,234,151,283,840,851,546,571,480,521,353,417,14,815,925,418,104,463,275,682
812,802,560,186,638,891,825,196,454,505,935,496,354,724,730,217,983,369,706,822
896,185,68,130,869,428,137,135,434,222,769,720,885,60,250,826,409,868,96,402
101,774,361,458,209,832,560,215,590,871,376,761,607,461,856,435,667,760,88,184
50,168,358,669,132,369,525,571,589,568,651,63,661,664,130,814,913,333,169,700
924,444,570,399,859,601,509,684,900,920,871,810,637,731,335,532,709,526,486,428
353,857,409,719,407,187,190,542,655,774,486,667,809,924,583,148,338,325,390,65
53,135,329,334,373,404,533,704,614,512,683,117,478,168,901,205,577,612,848,357
189,176,586,160,616,218,435,494,283,529,70,520,456,413,565,507,651,580,484,290
6,520,776,855,587,100,531,828,804,664,898,103,610,250,336,578,335,274,948,661
687,527,196,676,511,367,769,827,139,170,324,877,400,150,519,929,695,168,587,50
372,614,835,11,429,728,516,375,340,134,521,351,656,581,64,373,920,618,114,645
271,204,347,188,59,635,617,367,861,274,664,252,272,730,665,774,584,225,680,360
67,434,99,64,319,704,758,369,536,705,141,271,95,842,722,285,317,848,999,892
734,675,990,825,890,767,619,215,272,576,425,581,115,663,101,867,362,516,949,647
132,927,617,518,701,509,325,718,822,713,329,332,163,278,348,532,280,616,527,468
112,162,489,542,575,189,855,607,335,328,870,493,610,575,715,22,570,854,375,545
641,140,370,464,354,670,718,532,175,369,132,828,851,280,399,153,436,944,651,210
411,826,247,175,340,199,622,824,714,133,405,684,874,202,198,706,644,330,600,592
150,673,162,812,676,412,202,829,253,696,497,901,417,356,328,700,726,328,534,560
606,190,596,800,149,351,939,645,581,663,477,60,102,681,269,595,615,551,564,257
926,295,481,57,602,896,895,376,717,819,502,487,564,361,432,216,252,194,585,486
213,441,668,859,531,532,568,511,458,318,590,515,290,347,840,509,926,388,375,872
693,269,287,204,190,104,317,63,676,711,53,767,728,245,530,500,69,138,769,316
502,508,926,490,331,184,808,196,439,684,855,594,145,54,464,450,57,844,546,285
664,846,286,495,260,944,586,52,465,688,353,542,355,859,568,808,924,375,286,583
342,659,158,861,637,156,498,946,408,378,514,404,522,858,848,477,459,984,327,272
189,625,841,821,803,615,50,717,621,651,920,873,63,147,291,707,999,587,676,921
712,684,612,402,642,848,460,940,254,292,272,342,388,371,696,521,697,706,606,255
247,465,400,725,900,380,509,698,278,522,445,546,403,912,836,51,938,500,410,101
937,356,129,837,462,208,538,777,341,431,141,425,316,804,596,507,535,100,426,121
286,813,359,935,377,816,985,370,949,257,834,151,149,561,277,60,413,455,399,835
191,875,187,203,417,713,350,723,123,833,833,325,771,207,373,944,642,275,584,184
56,53,514,681,226,103,757,406,287,133,897,193,805,143,349,317,143,671,359,876
102,682,399,731,99,733,516,512,133,496,644,347,543,403,999,561,428,257,696,728
596,62,425,374,409,608,912,766,55,589,860,374,425,531,611,389,897,347,247,856
621,396,286,560,602,777,247,667,140,149,284,852,537,499,361,117,706,457,161,758
465,578,167,21,318,730,641,865,828,211,800,668,186,484,440,411,332,156,523,731
277,507,447,187,527,493,603,829,720,687,618,873,759,60,401,728,502,579,893,771
271,556,67,761,154,719,582,612,682,196,270,650,198,512,461,513,273,759,463,558
433,697,332,623,185,328,114,652,587,196,415,499,466,839,399,376,734,469,708,622
495,101,526,133,291,167,576,589,649,15,574,350,415,641,380,640,697,849,270,322
234,116,542,484,209,494,937,813,697,870,863,179,859,896,354,768,808,535,857,279
636,148,758,686,525,888,904,424,325,437,282,613,692,723,618,682,320,535,685,417
459,514,860,800,514,674,418,342,237,727,251,433,676,412,479,333,929,440,272,775
667,51,576,658,590,599,510,547,848,603,408,823,138,757,185,611,855,908,667,651
359,591,227,334,129,189,595,439,136,674,434,760,374,498,524,581,543,722,614,349
193,339,729,799,154,697,705,137,807,446,257,477,610,152,698,162,434,701,520,268
503,657,858,582,346,810,433,415,260,612,862,765,574,381,728,654,678,735,455,948
102,220,871,899,365,649,822,762,331,638,682,765,324,513,438,646,824,287,334,381
206,196,52,581,923,640,412,507,380,407,667,352,349,330,721,419,835,666,674,916
547,143,607,344,155,279,116,350,531,899,946,363,513,760,17,371,460,466,814,327
585,213,418,543,732,191,330,911,353,320,770,897,146,626,281,100,673,60,842,350
719,813,328,640,522,820,431,402,671,437,999,664,352,808,570,479,358,770,497,721
507,828,679,325,201,360,256,708,820,842,466,622,697,659,60,370,279,896,816,393
365,651,194,479,69,360,379,623,831,816,356,713,861,581,801,897,550,561,715,545
677,524,816,70,258,344,829,689,864,724,270,115,220,521,869,249,839,270,461,833
160,425,399,648,735,667,322,690,886,81,102,695,274,204,662,662,482,579,456,414
636,597,622,929,704,825,765,460,157,646,114,921,277,716,504,554,728,891,635,801
525,521,163,691,846,531,450,842,583,371,867,157,400,770,489,843,813,199,65,800
947,191,897,163,727,146,279,69,99,685,337,322,322,106,207,251,765,706,888,928
949,595,278,874,502,403,670,893,56,653,995,651,851,647,521,292,700,874,363,895
994,137,487,159,759,810,464,132,868,134,840,603,686,185,896,129,767,724,936,515
712,420,723,655,602,99,462,651,626,884,379,777,320,645,95,411,319,61,839,876
668,335,649,574,513,330,770,521,771,284,323,250,830,699,593,204,585,823,417,180
280,431,191,842,614,597,569,772,643,466,329,487,865,923,665,525,571,713,638,7
490,544,321,278,88,460,940,675,579,490,401,547,331,657,114,495,69,332,428,343
679,949,217,354,74,104,430,428,645,54,194,323,146,666,654,563,821,651,666,493
252,872,647,189,724,868,467,692,461,774,370,715,198,54,431,374,332,490,679,742
285,156,358,495,201,589,56,463,894,848,104,59,829,647,273,531,194,658,75,68
762,258,151,684,393,247,368,871,948,370,52,655,687,762,417,840,635,356,215,328
890,615,564,768,17,258,380,255,827,597,211,757,545,358,843,546,605,729,57,421
810,412,187,872,601,531,576,935,884,948,330,306,670,440,819,900,191,832,103,852
813,356,522,283,495,641,345,904,255,772,292,927,327,888,928,614,506,203,577,871
898,539,870,641,833,340,249,271,162,390,365,377,640,439,490,373,148,685,855,438
192,214,462,665,467,53,580,67,660,536,470,346,371,764,346,359,142,499,569,586
146,891,355,373,942,588,218,572,635,593,189,367,776,901,405,412,248,490,537,401
705,415,927,163,455,129,144,276,213,611,620,708,475,652,208,726,766,677,428,707
198,602,273,61,450,659,637,586,597,947,687,713,868,193,132,454,51,827,704,855
664,875,565,539,556,134,503,646,377,480,578,274,578,162,728,320,679,526,607,713
287,280,808,339,835,925,799,513,547,101,684,202,374,138,236,926,874,282,419,652
855,684,911,565,160,646,920,186,659,638,841,474,804,560,520,803,482,610,866,521
316,977,478,635,315,814,277,318,506,291,818,55,719,190,271,863,95,697,217,516
656,365,520,678,862,671,290,871,349,620,52,648,433,181,866,636,912,688,767,269
466,104,512,158,652,158,703,356,54,455,938,64,850,411,474,839,335,637,848,143
763,218,577,275,212,62,591,316,687,427,588,687,400,603,864,467,593,131,399,784
129,280,643,866,96,400,696,538,910,601,438,571,714,768,912,203,672,337,510,610
347,636,804,420,644,947,52,829,467,296,861,911,208,547,686,839,258,810,923,164
416,433,115,56,400,624,721,821,465,287,846,149,211,623,565,579,711,206,452,111
670,911,676,505,680,943,251,873,192,611,115,448,419,646,353,69,604,487,276,348
523,496,247,279,723,920,848,61,376,767,642,521,176,873,926,687,408,431,767,464
758,471,424,731,731,338,433,845,758,253,694,836,942,835,767,440,462,817,576,676
604,481,288,703,208,587,205,202,713,455,102,668,380,418,912,198,468,757,776,467
623,275,510,771,438,889,66,187,768,408,727,248,683,618,512,939,175,949,944,278
341,892,137,289,715,617,158,588,197,277,64,373,909,679,722,599,184,422,345,678
678,579,473,576,605,593,604,459,535,599,286,497,139,613,938,939,942,925,278,560
461,645,256,410,275,154,191,938,280,332,511,841,770,661,61,417,486,595,946,633
211,692,363,619,495,843,833,504,133,856,495,342,701,487,417,56,400,144,909,768
199,579,350,196,940,636,208,412,944,582,977,947,506,103,58,614,713,430,342,160
757,211,732,332,708,248,499,682,409,499,657,243,213,523,141,193,583,673,499,892
68,814,400,374,525,458,839,714,517,826,762,540,443,63,347,893,207,351,253,540
726,68,133,873,282,279,209,597,455,334,288,263,351,922,709,477,136,332,270,686
656,729,907,452,874,255,256,818,609,50,653,567,559,685,700,285,616,604,62,829
885,899,363,887,461,155,342,547,188,826,420,716,185,514,260,188,622,667,584,874
638,895,251,348,908,541,641,695,613,487,824,426,55,540,809,721,863,292,573,711
479,19,863,483,689,735,343,520,478,824,291,760,675,168,529,422,491,840,101,576
0,150,848,281,700,853,104,856,719,531,762,537,643,925,547,69,158,61,354,321
769,193,641,812,696,721,438,200,946,770,424,526,58,319,847,376,704,537,472,838
411,66,621,548,380,826,593,948,407,354,438,68,330,666,531,912,839,775,422,899
66,103,842,437,316,839,665,343,693,412,249,522,596,577,592,810,257,497,102,904
685,889,838,142,97,823,416,67,437,469,672,566,327,590,814,315,334,713,828,588
114,407,831,923,774,545,526,378,548,805,644,432,51,408,337,813,344,546,724,208
710,247,320,568,684,15,346,800,799,331,234,488,765,343,615,113,763,715,844,492
481,112,98,585,590,344,63,464,785,195,100,706,151,821,381,289,670,613,215,809
712,284,352,315,533,988,400,371,210,711,760,817,715,353,713,332,521,334,856,345
678,885,505,682,864,636,841,378,498,895,801,887,156,424,140,361,217,867,914,937
857,319,638,520,66,888,373,488,107,725,465,647,273,98,209,286,774,500,186,196
885,157,192,939,477,799,889,337,937,138,904,281,518,614,148,512,250,347,115,423
672,651,91,321,509,128,911,831,936,145,599,406,727,810,578,488,67,61,370,949
148,138,869,184,871,277,359,142,257,478,324,139,777,713,464,420,773,7,620,528
438,813,436,53,56,255,58,202,62,456,534,357,57,604,850,341,444,734,535,354
727,894,608,505,694,865,373,912,772,654,206,573,301,160,187,858,442,542,584,347
196,925,820,893,865,730,218,565,917,624,135,716,51,542,190,359,378,213,763,290
703,655,889,730,315,66,215,449,669,773,257,831,481,846,340,808,816,438,865,502
197,345,717,67,776,609,190,330,464,363,803,378,515,819,511,606,394,846,777,441
840,514,613,351,367,866,831,463,299,652,808,291,876,467,814,511,590,432,204,679
610,654,277,872,476,697,328,422,625,717,287,799,824,373,721,404,347,489,500,856
102,320,380,948,105,345,763,615,676,576,116,567,709,649,516,527,331,96,875,419
99,660,65,986,870,355,701,544,205,576,921,588,708,807,703,333,195,654,689,939
432,541,597,317,937,725,415,813,356,463,608,348,767,594,766,436,155,324,301,212
381,528,532,700,664,730,515,817,913,110,56,588,859,700,723,650,133,734,608,857
843,192,860,726,465,734,254,821,803,697,858,649,849,762,229,733,833,874,858,657
874,609,773,545,497,678,898,319,773,359,924,391,455,671,730,941,585,865,805,646
669,60,525,484,621,339,942,713,444,830,454,248,772,565,891,346,693,690,377,357
333,909,660,660,769,135,648,845,638,100,149,101,351,716,727,822,644,824,218,574
519,168,689,210,870,640,457,412,854,697,718,69,247,585,337,335,580,353,239,926
537,697,772,606,575,248,926,604,814,454,160,346,708,668,655,208,102,762,252,986
286,646,166,332,539,315,319,773,808,264,926,139,60,372,697,436,858,659,857,817
759,925,485,416,810,517,389,163,605,290,413,770,770,63,168,52,319,639,154,357
890,701,895,902,887,591,874,603,275,400,60,216,149,833,404,693,711,496,458,50
772,51,318,868,541,722,586,211,530,132,695,802,355,975,138,520,824,681,129,141
403,818,944,100,891,586,546,213,402,651,621,877,130,715,460,470,402,518,197,138
834,290,941,360,558,861,566,577,151,846,362,433,410,643,929,371,593,399,222,161
185,496,352,148,575,870,272,872,767,158,625,421,550,408,415,715,913,943,664,623
897,59,69,469,690,114,503,815,518,731,591,191,704,277,696,645,459,426,671,277
373,542,816,708,601,775,728,486,189,812,478,426,154,448,624,774,362,571,99,401
274,580,572,413,823,659,511,216,473,532,467,276,166,324,900,759,153,888,770,415
457,267,200,206,662,351,511,517,514,217,674,734,719,693,414,357,117,718,759,339
852,484,677,772,466,850,664,524,508,942,615,588,671,264,893,134,851,63,270,55
583,457,623,759,889,156,610,861,663,708,824,63,436,395,503,770,117,204,97,714
643,835,772,757,607,114,212,638,924,103,595,506,205,305,525,210,640,899,942,132
⛄"""