#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
void print_pairs_u16(unsigned short *a, size_t size) {
size_t i;
for (i = 0; i < size; i += 2) {
printf("[%u, %u]", a
[i
], a
[i
+ 1]); }
}
void print_pairs_u32(unsigned int *a, size_t size) {
size_t i;
for (i = 0; i < size; i += 2) {
printf("[%u, %u]", a
[i
], a
[i
+ 1]); }
}
static inline size_t find_index_u16(unsigned short *a, size_t size, unsigned int value) {
size_t i;
for (i = 0; i < size; i++) if (a[i] == value) return i;
return size;
}
static inline size_t find_index_u32(unsigned int *a, size_t size, unsigned int value) {
size_t i;
for (i = 0; i < size; i++) if (a[i] == value) return i;
return size;
}
#define print_pairs(a, n) _Generic((a), unsigned short * : print_pairs_u16, unsigned int * : print_pairs_u32, default : print_pairs_u32)((a), (n))
#define find_index(a, n, v) _Generic((a), unsigned short * : find_index_u16, unsigned int * : find_index_u32, default : find_index_u32)((a), (n), (v))
#define array_cap(a) (sizeof (a) / sizeof *(a))
#define array_print_as_pairs(a) print_pairs((a), array_cap(a))
#define array_find_index(a, v) find_index(a, array_cap(a), v)
typedef unsigned long long type_key;
typedef unsigned short type_value_elem;
typedef struct value {
type_value_elem values[4];
} type_value;
typedef struct entry {
type_key key;
type_value value;
} type_entry;
typedef unsigned int type_index;
typedef struct table {
type_index bin_power, entry_power, n_entries, *bins;
type_entry *entries;
} type_table;
static inline type_index bins_cap(type_table *table) {
return (type_index)1 << table->bin_power;
}
static inline type_index entries_cap(type_table *table) {
return (type_index)1 << table->entry_power;
}
static inline size_t bins_n_bytes(type_table *table) {
return sizeof *table->bins * bins_cap(table);
}
static inline size_t entries_n_bytes(type_table *table) {
return sizeof *table->entries * entries_cap(table);
}
void table_inspect_bins(type_table *table) {
for (size_t i = 0; i < bins_cap(table); i++)
printf("bins[%zu]: %u\n", i
, table
->bins
[i
]); }
void table_inspect(type_table *table) {
printf("bin_power: %u\n", table
->bin_power
); printf("entry_power: %u\n", table
->entry_power
); printf("n_entries: %u\n", table
->n_entries
); printf("bins: %p\n", table
->bins
); printf("entries: %p\n", table
->entries
); printf("bins_cap: %x %d\n", bins_cap
(table
), bins_cap
(table
)); printf("entries_cap: %x %d\n", entries_cap
(table
), entries_cap
(table
)); }
type_table *table_new(type_index bin_power, type_index entry_power) {
type_table
*table
= malloc(sizeof (type_table
)); table->bin_power = bin_power;
table->entry_power = entry_power;
table->n_entries = 0;
table
->bins
= malloc(bins_n_bytes
(table
)); table
->entries
= malloc(entries_n_bytes
(table
)); memset(table
->bins
, 0, bins_n_bytes
(table
)); if (!table || !table->bins || !table->entries)
fprintf(stderr
, "table_new: out of memory\n"), exit(EXIT_FAILURE
); return table;
}
void table_free(type_table *table) {
}
static inline type_index calc_bin_index(type_table *table, type_key key) {
return (bins_cap(table) - 1) & key;
}
static inline type_index find_bin_index(type_table *table, type_key key) {
type_index found = calc_bin_index(table, key);
type_index collision = 0;
type_index borderline = bins_cap(table) - 1;
type_index *bins = table->bins;
type_entry *entries = table->entries;
while (bins[found] && entries[bins[found]].key != key) {
collision++;
if (borderline < collision)
fprintf(stderr
, "borderline: %u, collision: %u\n", borderline
, collision
), exit(EXIT_FAILURE
); else
found = calc_bin_index(table, found + 1);
}
return found;
}
static inline void table_put_at(type_table *table, type_key key, type_value value, type_index bin_index) {
type_index borderline = entries_cap(table) - 1;
type_index *bins = table->bins;
type_entry *entries = table->entries;
if (!bins[bin_index]) {
// bins[x] == 0はビンが未使用という表現。そのため entries[0] は欠番。最初のデータは entries[1] に入る。
if (borderline < table->n_entries + 1)
fprintf(stderr
, "borderline: %u, (table->n_entries + 1): %u\n", borderline
, table
->n_entries
+ 1), exit(EXIT_FAILURE
); table->n_entries++;
bins[bin_index] = table->n_entries;
entries[bins[bin_index]] = (type_entry){key, value};
} else {
// 既存のエントリに上書き。
entries[bins[bin_index]] = (type_entry){key, value};
}
}
void table_put(type_table *table, type_key key, type_value value) {
return table_put_at(table, key, value, find_bin_index(table, key));
}
static inline type_value *table_get_at(type_table *table, type_index bin_index) {
type_index *bins = table->bins;
type_entry *entries = table->entries;
return !bins[bin_index] ? 0 : &entries[bins[bin_index]].value;
}
type_value *table_get(type_table *table, type_key key) {
return table_get_at(table, find_bin_index(table, key));
}
int table_contains_key(type_table *table, type_key key) {
return !!table_get(table, key);
}
type_index table_size(type_table *table) {
return table->n_entries;
}
static inline type_value *value_append(type_value *value, type_value_elem e) {
type_index cap = array_cap(value->values), i = array_find_index(value->values, 0);
if (i < cap)
value->values[i] = e;
else
fprintf(stderr
, "value->values cap: %u, required: %u\n", cap
, cap
+ 1), exit(EXIT_FAILURE
); return value;
}
struct answer {
type_key c;
type_value_elem pairs[10];
};
struct answer answer_from(type_value *value, type_value_elem last_b, type_key c) {
struct answer ans = {c};
size_t i, cap = array_cap(value->values);
type_value_elem a, b;
for (i = 0; i <= cap; i++) {
b = i < cap ? value->values[i] : last_b;
a = round(cbrt(c + (type_key)b * b * b));
ans.pairs[i * 2 + 0] = a;
ans.pairs[i * 2 + 1] = b;
}
return ans;
}
struct answer f(unsigned m) {
type_table *table = table_new(27, 24);
type_value *value = 0;
type_index index;
type_value_elem a, b;
type_key c;
struct answer ans;
for (a = 1; ; a++) {
for (b = 1; b < a; b++) {
c = (type_key)a * a * a - (type_key)b * b * b;
index = find_bin_index(table, c);
value = table_get_at(table, index);
if (!value)
table_put_at(table, c, (type_value){b}, index);
else if (array_find_index(value->values, 0) + 1 == m)
goto finally;
else
value_append(value, b);
}
}
finally:
ans = answer_from(value, b, c);
table_free(table);
return ans;
}
int main() {
struct answer ans = f(5);
array_print_as_pairs(ans.pairs);
return 0;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8bWF0aC5oPgp2b2lkIHByaW50X3BhaXJzX3UxNih1bnNpZ25lZCBzaG9ydCAqYSwgc2l6ZV90IHNpemUpIHsKICBzaXplX3QgaTsKICBwdXRjaGFyKCdbJyk7CiAgZm9yIChpID0gMDsgaSA8IHNpemU7IGkgKz0gMikgewogICAgaWYgKDAgPCBpKSBwcmludGYoIiwgIik7CiAgICBwcmludGYoIlsldSwgJXVdIiwgYVtpXSwgYVtpICsgMV0pOwogIH0KICBwdXRjaGFyKCddJyk7Cn0Kdm9pZCBwcmludF9wYWlyc191MzIodW5zaWduZWQgaW50ICphLCBzaXplX3Qgc2l6ZSkgewogIHNpemVfdCBpOwogIHB1dGNoYXIoJ1snKTsKICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSArPSAyKSB7CiAgICBpZiAoMCA8IGkpIHByaW50ZigiLCAiKTsKICAgIHByaW50ZigiWyV1LCAldV0iLCBhW2ldLCBhW2kgKyAxXSk7CiAgfQogIHB1dGNoYXIoJ10nKTsKfQpzdGF0aWMgaW5saW5lIHNpemVfdCBmaW5kX2luZGV4X3UxNih1bnNpZ25lZCBzaG9ydCAqYSwgc2l6ZV90IHNpemUsIHVuc2lnbmVkIGludCB2YWx1ZSkgewogIHNpemVfdCBpOwogIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIGlmIChhW2ldID09IHZhbHVlKSByZXR1cm4gaTsKICByZXR1cm4gc2l6ZTsKfQpzdGF0aWMgaW5saW5lIHNpemVfdCBmaW5kX2luZGV4X3UzMih1bnNpZ25lZCBpbnQgKmEsIHNpemVfdCBzaXplLCB1bnNpZ25lZCBpbnQgdmFsdWUpIHsKICBzaXplX3QgaTsKICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSBpZiAoYVtpXSA9PSB2YWx1ZSkgcmV0dXJuIGk7CiAgcmV0dXJuIHNpemU7Cn0KI2RlZmluZSBwcmludF9wYWlycyhhLCBuKSBfR2VuZXJpYygoYSksIHVuc2lnbmVkIHNob3J0ICogOiBwcmludF9wYWlyc191MTYsIHVuc2lnbmVkIGludCAqIDogcHJpbnRfcGFpcnNfdTMyLCBkZWZhdWx0IDogcHJpbnRfcGFpcnNfdTMyKSgoYSksIChuKSkKI2RlZmluZSBmaW5kX2luZGV4KGEsIG4sIHYpIF9HZW5lcmljKChhKSwgdW5zaWduZWQgc2hvcnQgKiA6IGZpbmRfaW5kZXhfdTE2LCB1bnNpZ25lZCBpbnQgKiA6IGZpbmRfaW5kZXhfdTMyLCBkZWZhdWx0IDogZmluZF9pbmRleF91MzIpKChhKSwgKG4pLCAodikpCiNkZWZpbmUgYXJyYXlfY2FwKGEpIChzaXplb2YgKGEpIC8gc2l6ZW9mICooYSkpCiNkZWZpbmUgYXJyYXlfcHJpbnRfYXNfcGFpcnMoYSkgcHJpbnRfcGFpcnMoKGEpLCBhcnJheV9jYXAoYSkpCiNkZWZpbmUgYXJyYXlfZmluZF9pbmRleChhLCB2KSBmaW5kX2luZGV4KGEsIGFycmF5X2NhcChhKSwgdikKCnR5cGVkZWYgdW5zaWduZWQgbG9uZyBsb25nIHR5cGVfa2V5Owp0eXBlZGVmIHVuc2lnbmVkIHNob3J0IHR5cGVfdmFsdWVfZWxlbTsKdHlwZWRlZiBzdHJ1Y3QgdmFsdWUgewogIHR5cGVfdmFsdWVfZWxlbSB2YWx1ZXNbNF07Cn0gdHlwZV92YWx1ZTsKdHlwZWRlZiBzdHJ1Y3QgZW50cnkgewogIHR5cGVfa2V5IGtleTsKICB0eXBlX3ZhbHVlIHZhbHVlOwp9IHR5cGVfZW50cnk7CnR5cGVkZWYgdW5zaWduZWQgaW50IHR5cGVfaW5kZXg7CnR5cGVkZWYgc3RydWN0IHRhYmxlIHsKICB0eXBlX2luZGV4IGJpbl9wb3dlciwgZW50cnlfcG93ZXIsIG5fZW50cmllcywgKmJpbnM7CiAgdHlwZV9lbnRyeSAqZW50cmllczsKfSB0eXBlX3RhYmxlOwpzdGF0aWMgaW5saW5lIHR5cGVfaW5kZXggYmluc19jYXAodHlwZV90YWJsZSAqdGFibGUpIHsKICByZXR1cm4gKHR5cGVfaW5kZXgpMSA8PCB0YWJsZS0+YmluX3Bvd2VyOwp9CnN0YXRpYyBpbmxpbmUgdHlwZV9pbmRleCBlbnRyaWVzX2NhcCh0eXBlX3RhYmxlICp0YWJsZSkgewogIHJldHVybiAodHlwZV9pbmRleCkxIDw8IHRhYmxlLT5lbnRyeV9wb3dlcjsKfQpzdGF0aWMgaW5saW5lIHNpemVfdCBiaW5zX25fYnl0ZXModHlwZV90YWJsZSAqdGFibGUpIHsKICByZXR1cm4gc2l6ZW9mICp0YWJsZS0+YmlucyAqIGJpbnNfY2FwKHRhYmxlKTsKfQpzdGF0aWMgaW5saW5lIHNpemVfdCBlbnRyaWVzX25fYnl0ZXModHlwZV90YWJsZSAqdGFibGUpIHsKICByZXR1cm4gc2l6ZW9mICp0YWJsZS0+ZW50cmllcyAqIGVudHJpZXNfY2FwKHRhYmxlKTsKfQp2b2lkIHRhYmxlX2luc3BlY3RfYmlucyh0eXBlX3RhYmxlICp0YWJsZSkgewogIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYmluc19jYXAodGFibGUpOyBpKyspCiAgICBwcmludGYoImJpbnNbJXp1XTogJXVcbiIsIGksIHRhYmxlLT5iaW5zW2ldKTsKfQp2b2lkIHRhYmxlX2luc3BlY3QodHlwZV90YWJsZSAqdGFibGUpIHsKICBwcmludGYoInRhYmxlOiAlcFxuIiwgdGFibGUpOwogIHByaW50ZigiYmluX3Bvd2VyOiAldVxuIiwgdGFibGUtPmJpbl9wb3dlcik7CiAgcHJpbnRmKCJlbnRyeV9wb3dlcjogJXVcbiIsIHRhYmxlLT5lbnRyeV9wb3dlcik7CiAgcHJpbnRmKCJuX2VudHJpZXM6ICV1XG4iLCB0YWJsZS0+bl9lbnRyaWVzKTsKICBwcmludGYoImJpbnM6ICVwXG4iLCB0YWJsZS0+Ymlucyk7CiAgcHJpbnRmKCJlbnRyaWVzOiAlcFxuIiwgdGFibGUtPmVudHJpZXMpOwogIHByaW50ZigiYmluc19jYXA6ICV4ICVkXG4iLCBiaW5zX2NhcCh0YWJsZSksIGJpbnNfY2FwKHRhYmxlKSk7CiAgcHJpbnRmKCJlbnRyaWVzX2NhcDogJXggJWRcbiIsIGVudHJpZXNfY2FwKHRhYmxlKSwgZW50cmllc19jYXAodGFibGUpKTsKfQp0eXBlX3RhYmxlICp0YWJsZV9uZXcodHlwZV9pbmRleCBiaW5fcG93ZXIsIHR5cGVfaW5kZXggZW50cnlfcG93ZXIpIHsKICB0eXBlX3RhYmxlICp0YWJsZSA9IG1hbGxvYyhzaXplb2YgKHR5cGVfdGFibGUpKTsKICB0YWJsZS0+YmluX3Bvd2VyID0gYmluX3Bvd2VyOwogIHRhYmxlLT5lbnRyeV9wb3dlciA9IGVudHJ5X3Bvd2VyOwogIHRhYmxlLT5uX2VudHJpZXMgPSAwOwogIHRhYmxlLT5iaW5zID0gbWFsbG9jKGJpbnNfbl9ieXRlcyh0YWJsZSkpOwogIHRhYmxlLT5lbnRyaWVzID0gbWFsbG9jKGVudHJpZXNfbl9ieXRlcyh0YWJsZSkpOwogIG1lbXNldCh0YWJsZS0+YmlucywgMCwgYmluc19uX2J5dGVzKHRhYmxlKSk7CiAgaWYgKCF0YWJsZSB8fCAhdGFibGUtPmJpbnMgfHwgIXRhYmxlLT5lbnRyaWVzKQogICAgZnByaW50ZihzdGRlcnIsICJ0YWJsZV9uZXc6IG91dCBvZiBtZW1vcnlcbiIpLCBleGl0KEVYSVRfRkFJTFVSRSk7CiAgcmV0dXJuIHRhYmxlOwp9CnZvaWQgdGFibGVfZnJlZSh0eXBlX3RhYmxlICp0YWJsZSkgewogIGZyZWUodGFibGUtPmJpbnMpLCBmcmVlKHRhYmxlLT5lbnRyaWVzKSwgZnJlZSh0YWJsZSk7Cn0Kc3RhdGljIGlubGluZSB0eXBlX2luZGV4IGNhbGNfYmluX2luZGV4KHR5cGVfdGFibGUgKnRhYmxlLCB0eXBlX2tleSBrZXkpIHsKICByZXR1cm4gKGJpbnNfY2FwKHRhYmxlKSAtIDEpICYga2V5Owp9CnN0YXRpYyBpbmxpbmUgdHlwZV9pbmRleCBmaW5kX2Jpbl9pbmRleCh0eXBlX3RhYmxlICp0YWJsZSwgdHlwZV9rZXkga2V5KSB7CiAgdHlwZV9pbmRleCBmb3VuZCA9IGNhbGNfYmluX2luZGV4KHRhYmxlLCBrZXkpOwogIHR5cGVfaW5kZXggY29sbGlzaW9uID0gMDsKICB0eXBlX2luZGV4IGJvcmRlcmxpbmUgPSBiaW5zX2NhcCh0YWJsZSkgLSAxOwogIHR5cGVfaW5kZXggKmJpbnMgPSB0YWJsZS0+YmluczsKICB0eXBlX2VudHJ5ICplbnRyaWVzID0gdGFibGUtPmVudHJpZXM7CiAgd2hpbGUgKGJpbnNbZm91bmRdICYmIGVudHJpZXNbYmluc1tmb3VuZF1dLmtleSAhPSBrZXkpIHsKICAgIGNvbGxpc2lvbisrOwogICAgaWYgKGJvcmRlcmxpbmUgPCBjb2xsaXNpb24pCiAgICAgIGZwcmludGYoc3RkZXJyLCAiYm9yZGVybGluZTogJXUsIGNvbGxpc2lvbjogJXVcbiIsIGJvcmRlcmxpbmUsIGNvbGxpc2lvbiksIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgIGVsc2UKICAgICAgZm91bmQgPSBjYWxjX2Jpbl9pbmRleCh0YWJsZSwgZm91bmQgKyAxKTsKICB9CiAgcmV0dXJuIGZvdW5kOwp9CnN0YXRpYyBpbmxpbmUgdm9pZCB0YWJsZV9wdXRfYXQodHlwZV90YWJsZSAqdGFibGUsIHR5cGVfa2V5IGtleSwgdHlwZV92YWx1ZSB2YWx1ZSwgdHlwZV9pbmRleCBiaW5faW5kZXgpIHsKICB0eXBlX2luZGV4IGJvcmRlcmxpbmUgPSBlbnRyaWVzX2NhcCh0YWJsZSkgLSAxOwogIHR5cGVfaW5kZXggKmJpbnMgPSB0YWJsZS0+YmluczsKICB0eXBlX2VudHJ5ICplbnRyaWVzID0gdGFibGUtPmVudHJpZXM7CiAgaWYgKCFiaW5zW2Jpbl9pbmRleF0pIHsKICAgIC8vIGJpbnNbeF0gPT0gMOOBr+ODk+ODs+OBjOacquS9v+eUqOOBqOOBhOOBhuihqOePvuOAguOBneOBruOBn+OCgSBlbnRyaWVzWzBdIOOBr+asoOeVquOAguacgOWIneOBruODh+ODvOOCv+OBryBlbnRyaWVzWzFdIOOBq+WFpeOCi+OAggogICAgaWYgKGJvcmRlcmxpbmUgPCB0YWJsZS0+bl9lbnRyaWVzICsgMSkKICAgICAgZnByaW50ZihzdGRlcnIsICJib3JkZXJsaW5lOiAldSwgKHRhYmxlLT5uX2VudHJpZXMgKyAxKTogJXVcbiIsIGJvcmRlcmxpbmUsIHRhYmxlLT5uX2VudHJpZXMgKyAxKSwgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgdGFibGUtPm5fZW50cmllcysrOwogICAgYmluc1tiaW5faW5kZXhdID0gdGFibGUtPm5fZW50cmllczsKICAgIGVudHJpZXNbYmluc1tiaW5faW5kZXhdXSA9ICh0eXBlX2VudHJ5KXtrZXksIHZhbHVlfTsKICB9IGVsc2UgewogICAgLy8g5pei5a2Y44Gu44Ko44Oz44OI44Oq44Gr5LiK5pu444GN44CCCiAgICBlbnRyaWVzW2JpbnNbYmluX2luZGV4XV0gPSAodHlwZV9lbnRyeSl7a2V5LCB2YWx1ZX07CiAgfQp9CnZvaWQgdGFibGVfcHV0KHR5cGVfdGFibGUgKnRhYmxlLCB0eXBlX2tleSBrZXksIHR5cGVfdmFsdWUgdmFsdWUpIHsKICByZXR1cm4gdGFibGVfcHV0X2F0KHRhYmxlLCBrZXksIHZhbHVlLCBmaW5kX2Jpbl9pbmRleCh0YWJsZSwga2V5KSk7Cn0Kc3RhdGljIGlubGluZSB0eXBlX3ZhbHVlICp0YWJsZV9nZXRfYXQodHlwZV90YWJsZSAqdGFibGUsIHR5cGVfaW5kZXggYmluX2luZGV4KSB7CiAgdHlwZV9pbmRleCAqYmlucyA9IHRhYmxlLT5iaW5zOwogIHR5cGVfZW50cnkgKmVudHJpZXMgPSB0YWJsZS0+ZW50cmllczsKICByZXR1cm4gIWJpbnNbYmluX2luZGV4XSA/IDAgOiAmZW50cmllc1tiaW5zW2Jpbl9pbmRleF1dLnZhbHVlOwp9CnR5cGVfdmFsdWUgKnRhYmxlX2dldCh0eXBlX3RhYmxlICp0YWJsZSwgdHlwZV9rZXkga2V5KSB7CiAgcmV0dXJuIHRhYmxlX2dldF9hdCh0YWJsZSwgZmluZF9iaW5faW5kZXgodGFibGUsIGtleSkpOwp9CmludCB0YWJsZV9jb250YWluc19rZXkodHlwZV90YWJsZSAqdGFibGUsIHR5cGVfa2V5IGtleSkgewogIHJldHVybiAhIXRhYmxlX2dldCh0YWJsZSwga2V5KTsKfQp0eXBlX2luZGV4IHRhYmxlX3NpemUodHlwZV90YWJsZSAqdGFibGUpIHsKICByZXR1cm4gdGFibGUtPm5fZW50cmllczsKfQoKc3RhdGljIGlubGluZSB0eXBlX3ZhbHVlICp2YWx1ZV9hcHBlbmQodHlwZV92YWx1ZSAqdmFsdWUsIHR5cGVfdmFsdWVfZWxlbSBlKSB7CiAgdHlwZV9pbmRleCBjYXAgPSBhcnJheV9jYXAodmFsdWUtPnZhbHVlcyksIGkgPSBhcnJheV9maW5kX2luZGV4KHZhbHVlLT52YWx1ZXMsIDApOwogIGlmIChpIDwgY2FwKQogICAgdmFsdWUtPnZhbHVlc1tpXSA9IGU7CiAgZWxzZQogICAgZnByaW50ZihzdGRlcnIsICJ2YWx1ZS0+dmFsdWVzIGNhcDogJXUsIHJlcXVpcmVkOiAldVxuIiwgY2FwLCBjYXAgKyAxKSwgZXhpdChFWElUX0ZBSUxVUkUpOwogIHJldHVybiB2YWx1ZTsKfQpzdHJ1Y3QgYW5zd2VyIHsKICB0eXBlX2tleSBjOwogIHR5cGVfdmFsdWVfZWxlbSBwYWlyc1sxMF07Cn07CnN0cnVjdCBhbnN3ZXIgYW5zd2VyX2Zyb20odHlwZV92YWx1ZSAqdmFsdWUsIHR5cGVfdmFsdWVfZWxlbSBsYXN0X2IsIHR5cGVfa2V5IGMpIHsKICBzdHJ1Y3QgYW5zd2VyIGFucyA9IHtjfTsKICBzaXplX3QgaSwgY2FwID0gYXJyYXlfY2FwKHZhbHVlLT52YWx1ZXMpOwogIHR5cGVfdmFsdWVfZWxlbSBhLCBiOwogIGZvciAoaSA9IDA7IGkgPD0gY2FwOyBpKyspIHsKICAgIGIgPSBpIDwgY2FwID8gdmFsdWUtPnZhbHVlc1tpXSA6IGxhc3RfYjsKICAgIGEgPSByb3VuZChjYnJ0KGMgKyAodHlwZV9rZXkpYiAqIGIgKiBiKSk7CiAgICBhbnMucGFpcnNbaSAqIDIgKyAwXSA9IGE7CiAgICBhbnMucGFpcnNbaSAqIDIgKyAxXSA9IGI7CiAgfQogIHJldHVybiBhbnM7Cn0Kc3RydWN0IGFuc3dlciBmKHVuc2lnbmVkIG0pIHsKICB0eXBlX3RhYmxlICp0YWJsZSA9IHRhYmxlX25ldygyNywgMjQpOwogIHR5cGVfdmFsdWUgKnZhbHVlID0gMDsKICB0eXBlX2luZGV4IGluZGV4OwogIHR5cGVfdmFsdWVfZWxlbSBhLCBiOwogIHR5cGVfa2V5IGM7CiAgc3RydWN0IGFuc3dlciBhbnM7CiAgZm9yIChhID0gMTsgOyBhKyspIHsKICAgIGZvciAoYiA9IDE7IGIgPCBhOyBiKyspIHsKICAgICAgYyA9ICh0eXBlX2tleSlhICogYSAqIGEgLSAodHlwZV9rZXkpYiAqIGIgKiBiOwogICAgICBpbmRleCA9IGZpbmRfYmluX2luZGV4KHRhYmxlLCBjKTsKICAgICAgdmFsdWUgPSB0YWJsZV9nZXRfYXQodGFibGUsIGluZGV4KTsKICAgICAgaWYgKCF2YWx1ZSkgCiAgICAgICAgdGFibGVfcHV0X2F0KHRhYmxlLCBjLCAodHlwZV92YWx1ZSl7Yn0sIGluZGV4KTsKICAgICAgZWxzZSBpZiAoYXJyYXlfZmluZF9pbmRleCh2YWx1ZS0+dmFsdWVzLCAwKSArIDEgPT0gbSkgCiAgICAgICAgZ290byBmaW5hbGx5OwogICAgICBlbHNlIAogICAgICAgIHZhbHVlX2FwcGVuZCh2YWx1ZSwgYik7CiAgICB9CiAgfQogZmluYWxseToKICBhbnMgPSBhbnN3ZXJfZnJvbSh2YWx1ZSwgYiwgYyk7CiAgdGFibGVfZnJlZSh0YWJsZSk7CiAgcmV0dXJuIGFuczsKfQppbnQgbWFpbigpIHsKICBzdHJ1Y3QgYW5zd2VyIGFucyA9IGYoNSk7CiAgYXJyYXlfcHJpbnRfYXNfcGFpcnMoYW5zLnBhaXJzKTsKICByZXR1cm4gMDsKfQo=