- #include <iostream> 
- #include <string> 
- #include <ctime> 
- #include <random> 
- #include <algorithm>    // std::min 
-   
- using namespace std; 
-   
- const int MAX_N = 5000; 
-   
- int seg[2 * MAX_N]; 
- int segsL[MAX_N][2 * MAX_N]; 
- int m[MAX_N][MAX_N][2]; 
- int dp[MAX_N][MAX_N]; 
- int best; 
-   
- // Adapted from https://c...content-available-to-author-only...s.com/blog/entry/18051 
- void update(int n, int p, int value) { // set value at position p 
-   for (seg[p += n] = value; p > 1; p >>= 1) 
-     seg[p >> 1] = seg[p] + seg[p ^ 1]; 
- } 
- // Adapted from https://c...content-available-to-author-only...s.com/blog/entry/18051 
- int query(int n, int l, int r) { // sum on interval [l, r) 
-   int res = 0; 
-   for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 
-     if (l & 1) res += seg[l++]; 
-     if (r & 1) res += seg[--r]; 
-   } 
-   return res; 
- } 
- // Adapted from https://c...content-available-to-author-only...s.com/blog/entry/18051 
- void updateL(int n, int i, int p, int value) { // set value at position p 
-   for (segsL[i][p += n] = value; p > 1; p >>= 1) 
-     segsL[i][p >> 1] = segsL[i][p] + segsL[i][p ^ 1]; 
- } 
- // Adapted from https://c...content-available-to-author-only...s.com/blog/entry/18051 
- int queryL(int n, int i, int l, int r) { // sum on interval [l, r) 
-   int res = 0; 
-   for (l += n, r += n; l < r; l >>= 1, r >>= 1) { 
-     if (l & 1) res += segsL[i][l++]; 
-     if (r & 1) res += segsL[i][--r]; 
-   } 
-   return res; 
- } 
-   
- // Code by גלעד ברקן 
- void precalc(int n, string & s) { 
-   int i, j; 
-   for (i = 0; i < n; i++) { 
-     for (j = 0; j < n; j++) { 
-       // [longest match left, longest match right] 
-       m[i][j][0] = (s[i] == s[j]) & 1; 
-       m[i][j][1] = (s[i] == s[j]) & 1; 
-     } 
-   } 
-   
-   for (i = n - 2; i >= 0; i--) 
-     for (j = n - 2; j >= 0; j--) 
-       m[i][j][1] = s[i] == s[j] ? 1 + m[i + 1][j + 1][1] : 0; 
-   
-   for (i = 1; i < n; i++) 
-     for (j = 1; j < n; j++) 
-       m[i][j][0] = s[i] == s[j] ? 1 + m[i - 1][j - 1][0] : 0; 
- } 
-   
- // Code by גלעד ברקן 
- void f(int n, string & s) { 
-   int i, j, k, longest; 
-   
-   dp[0][n - 1] = 1; 
-   update(n, n - 1, 1); 
-   updateL(n, n - 1, 0, 1); 
-   
-   // Right side initialisation 
-   for (j = n - 2; j >= 0; j--) { 
-     if (s[0] == s[j + 1]) { 
-       longest = std::min(j + 1, m[0][j + 1][1]); 
-       for (k = j + 1; k <= j + longest; k++) 
-         dp[0][j] |= dp[0][k]; 
-       if (dp[0][j]) { 
-         update(n, j, 1); 
-         updateL(n, j, 0, 1); 
-         best = std::min(best, j + 1); 
-       } 
-     } 
-   } 
-   
-   // Left side initialisation 
-   for (i = 1; i < n; i++) { 
-     if (s[i - 1] == s[n - 1]) { 
-       // We are bound by the current range 
-       longest = std::min(n - i, m[i - 1][n - 1][0]); 
-       for (k = i - 1; k >= i - longest; k--) 
-         dp[i][n - 1] |= dp[k][n - 1]; 
-       if (dp[i][n - 1]) { 
-         updateL(n, n - 1, i, 1); 
-         best = std::min(best, n - i); 
-       } 
-     } 
-   } 
-   
-   for (i = 1; i <= n - 2; i++) { 
-     for (int ii = 0; ii < MAX_N; ii++) { 
-       seg[ii * 2] = 0; 
-       seg[ii * 2 + 1] = 0; 
-     } 
-     update(n, n - 1, dp[i][n - 1]); 
-     for (j = n - 2; j >= i; j--) { 
-       // We removed on the right 
-       if (s[i] == s[j + 1]) { 
-         // We are bound by half the current range 
-         longest = std::min(j - i + 1, m[i][j + 1][1]); 
-         //for (k=j+1; k<=j+longest; k++) 
-         //dp[i][j] |= dp[i][k]; 
-         if (query(n, j + 1, j + longest + 1)) { 
-           dp[i][j] = 1; 
-           update(n, j, 1); 
-           updateL(n, j, i, 1); 
-         } 
-       } 
-       // We removed on the left 
-       if (s[i - 1] == s[j]) { 
-         // We are bound by half the current range 
-         longest = std::min(j - i + 1, m[i - 1][j][0]); 
-         //for (k=i-1; k>=i-longest; k--) 
-         //dp[i][j] |= dp[k][j]; 
-         if (queryL(n, j, i - longest, i)) { 
-           dp[i][j] = 1; 
-           updateL(n, j, i, 1); 
-           update(n, j, 1); 
-         } 
-       } 
-       if (dp[i][j]) 
-         best = std::min(best, j - i + 1); 
-     } 
-   } 
- } 
-   
- int so(string s) { 
-   for (int i = 0; i < MAX_N; i++) { 
-     seg[i * 2] = 0; 
-     seg[i * 2 + 1] = 0; 
-     for (int j = 0; j < MAX_N; j++) { 
-       segsL[i][j * 2] = 0; 
-       segsL[i][j * 2 + 1] = 0; 
-       m[i][j][0] = 0; 
-       m[i][j][1] = 0; 
-       dp[i][j] = 0; 
-     } 
-   } 
-   int n = s.length(); 
-   best = n; 
-   precalc(n, s); 
-   f(n, s); 
-   return best; 
- } 
- // End code by גלעד ברקן 
-   
- // Code by Bananon  ======================================================================= 
-   
- int result; 
-   
- int lps[MAX_N][MAX_N]; 
- bool checked[MAX_N][MAX_N]; 
-   
- void check(int start, int length) { 
-   checked[start][length] = true; 
-   if (length < result) { 
-     result = length; 
-   } 
-   for (int i = lps[start][length]; i != 0; i = lps[start][i - 1]) { 
-     int newLength = length - i; 
-     if (!checked[start][newLength]) 
-       check(start, newLength); 
-     int newStart = start + i; 
-     if (!checked[newStart][newLength]) 
-       check(newStart, newLength); 
-   } 
- } 
-   
- int my(string str) { 
-   int n = str.length(); 
-   for (int l = 0; l < n; l++) { 
-     int subLength = n - l; 
-     lps[l][0] = 0; 
-     checked[l][0] = false; 
-     for (int i = 1; i < subLength; ++i) { 
-       int j = lps[l][i - 1]; 
-       while (j > 0 && str[i + l] != str[j + l]) 
-         j = lps[l][j - 1]; 
-       if (str[i + l] == str[j + l]) j++; 
-       lps[l][i] = j; 
-       checked[l][i] = false; 
-     } 
-   } 
-   result = n - 1; 
-   check(0, n - 1); 
-   return result + 1; 
- } 
-   
- // generate ================================================================= 
-   
- bool rndBool() { 
-   return rand() % 2 == 0; 
- } 
-   
- int rnd(int bound) { 
-   return rand() % bound; 
- } 
-   
- void untrim(string & str) { 
-   int length = rnd(str.length()); 
-   int prefixLength = rnd(str.length()) + 1; 
-   if (rndBool()) 
-     str.append(str.substr(0, prefixLength)); 
-   else { 
-     string newStr = str.substr(str.length() - prefixLength, prefixLength); 
-     newStr.append(str); 
-     str = newStr; 
-   } 
- } 
-   
- void rndTest(int minTestLength, string s) { 
-   while (s.length() < minTestLength) 
-     untrim(s); 
-   int myAns = my(s); 
-   int soAns = so(s); 
-   cout << myAns << " " << soAns << '\n'; 
-   if (soAns != myAns) { 
-     cout << s; 
-     exit(0); 
-   } 
- } 
-   
- int main() { 
-   int minTestLength; 
-   cin >> minTestLength; 
-   string seed; 
-   cin >> seed; 
-   while (true) 
-     rndTest(minTestLength, seed); 
- } 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8Y3RpbWU+CiNpbmNsdWRlIDxyYW5kb20+CiNpbmNsdWRlIDxhbGdvcml0aG0+ICAgIC8vIHN0ZDo6bWluCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgaW50IE1BWF9OID0gNTAwMDsKCmludCBzZWdbMiAqIE1BWF9OXTsKaW50IHNlZ3NMW01BWF9OXVsyICogTUFYX05dOwppbnQgbVtNQVhfTl1bTUFYX05dWzJdOwppbnQgZHBbTUFYX05dW01BWF9OXTsKaW50IGJlc3Q7CgovLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9jLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9ibG9nL2VudHJ5LzE4MDUxCnZvaWQgdXBkYXRlKGludCBuLCBpbnQgcCwgaW50IHZhbHVlKSB7IC8vIHNldCB2YWx1ZSBhdCBwb3NpdGlvbiBwCiAgZm9yIChzZWdbcCArPSBuXSA9IHZhbHVlOyBwID4gMTsgcCA+Pj0gMSkKICAgIHNlZ1twID4+IDFdID0gc2VnW3BdICsgc2VnW3AgXiAxXTsKfQovLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9jLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9ibG9nL2VudHJ5LzE4MDUxCmludCBxdWVyeShpbnQgbiwgaW50IGwsIGludCByKSB7IC8vIHN1bSBvbiBpbnRlcnZhbCBbbCwgcikKICBpbnQgcmVzID0gMDsKICBmb3IgKGwgKz0gbiwgciArPSBuOyBsIDwgcjsgbCA+Pj0gMSwgciA+Pj0gMSkgewogICAgaWYgKGwgJiAxKSByZXMgKz0gc2VnW2wrK107CiAgICBpZiAociAmIDEpIHJlcyArPSBzZWdbLS1yXTsKICB9CiAgcmV0dXJuIHJlczsKfQovLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9jLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9ibG9nL2VudHJ5LzE4MDUxCnZvaWQgdXBkYXRlTChpbnQgbiwgaW50IGksIGludCBwLCBpbnQgdmFsdWUpIHsgLy8gc2V0IHZhbHVlIGF0IHBvc2l0aW9uIHAKICBmb3IgKHNlZ3NMW2ldW3AgKz0gbl0gPSB2YWx1ZTsgcCA+IDE7IHAgPj49IDEpCiAgICBzZWdzTFtpXVtwID4+IDFdID0gc2Vnc0xbaV1bcF0gKyBzZWdzTFtpXVtwIF4gMV07Cn0KLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vYy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ucy5jb20vYmxvZy9lbnRyeS8xODA1MQppbnQgcXVlcnlMKGludCBuLCBpbnQgaSwgaW50IGwsIGludCByKSB7IC8vIHN1bSBvbiBpbnRlcnZhbCBbbCwgcikKICBpbnQgcmVzID0gMDsKICBmb3IgKGwgKz0gbiwgciArPSBuOyBsIDwgcjsgbCA+Pj0gMSwgciA+Pj0gMSkgewogICAgaWYgKGwgJiAxKSByZXMgKz0gc2Vnc0xbaV1bbCsrXTsKICAgIGlmIChyICYgMSkgcmVzICs9IHNlZ3NMW2ldWy0tcl07CiAgfQogIHJldHVybiByZXM7Cn0KCi8vIENvZGUgYnkg15LXnNei15Mg15HXqNen158Kdm9pZCBwcmVjYWxjKGludCBuLCBzdHJpbmcgJiBzKSB7CiAgaW50IGksIGo7CiAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgewogICAgZm9yIChqID0gMDsgaiA8IG47IGorKykgewogICAgICAvLyBbbG9uZ2VzdCBtYXRjaCBsZWZ0LCBsb25nZXN0IG1hdGNoIHJpZ2h0XQogICAgICBtW2ldW2pdWzBdID0gKHNbaV0gPT0gc1tqXSkgJiAxOwogICAgICBtW2ldW2pdWzFdID0gKHNbaV0gPT0gc1tqXSkgJiAxOwogICAgfQogIH0KCiAgZm9yIChpID0gbiAtIDI7IGkgPj0gMDsgaS0tKQogICAgZm9yIChqID0gbiAtIDI7IGogPj0gMDsgai0tKQogICAgICBtW2ldW2pdWzFdID0gc1tpXSA9PSBzW2pdID8gMSArIG1baSArIDFdW2ogKyAxXVsxXSA6IDA7CgogIGZvciAoaSA9IDE7IGkgPCBuOyBpKyspCiAgICBmb3IgKGogPSAxOyBqIDwgbjsgaisrKQogICAgICBtW2ldW2pdWzBdID0gc1tpXSA9PSBzW2pdID8gMSArIG1baSAtIDFdW2ogLSAxXVswXSA6IDA7Cn0KCi8vIENvZGUgYnkg15LXnNei15Mg15HXqNen158Kdm9pZCBmKGludCBuLCBzdHJpbmcgJiBzKSB7CiAgaW50IGksIGosIGssIGxvbmdlc3Q7CgogIGRwWzBdW24gLSAxXSA9IDE7CiAgdXBkYXRlKG4sIG4gLSAxLCAxKTsKICB1cGRhdGVMKG4sIG4gLSAxLCAwLCAxKTsKCiAgLy8gUmlnaHQgc2lkZSBpbml0aWFsaXNhdGlvbgogIGZvciAoaiA9IG4gLSAyOyBqID49IDA7IGotLSkgewogICAgaWYgKHNbMF0gPT0gc1tqICsgMV0pIHsKICAgICAgbG9uZ2VzdCA9IHN0ZDo6bWluKGogKyAxLCBtWzBdW2ogKyAxXVsxXSk7CiAgICAgIGZvciAoayA9IGogKyAxOyBrIDw9IGogKyBsb25nZXN0OyBrKyspCiAgICAgICAgZHBbMF1bal0gfD0gZHBbMF1ba107CiAgICAgIGlmIChkcFswXVtqXSkgewogICAgICAgIHVwZGF0ZShuLCBqLCAxKTsKICAgICAgICB1cGRhdGVMKG4sIGosIDAsIDEpOwogICAgICAgIGJlc3QgPSBzdGQ6Om1pbihiZXN0LCBqICsgMSk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIExlZnQgc2lkZSBpbml0aWFsaXNhdGlvbgogIGZvciAoaSA9IDE7IGkgPCBuOyBpKyspIHsKICAgIGlmIChzW2kgLSAxXSA9PSBzW24gLSAxXSkgewogICAgICAvLyBXZSBhcmUgYm91bmQgYnkgdGhlIGN1cnJlbnQgcmFuZ2UKICAgICAgbG9uZ2VzdCA9IHN0ZDo6bWluKG4gLSBpLCBtW2kgLSAxXVtuIC0gMV1bMF0pOwogICAgICBmb3IgKGsgPSBpIC0gMTsgayA+PSBpIC0gbG9uZ2VzdDsgay0tKQogICAgICAgIGRwW2ldW24gLSAxXSB8PSBkcFtrXVtuIC0gMV07CiAgICAgIGlmIChkcFtpXVtuIC0gMV0pIHsKICAgICAgICB1cGRhdGVMKG4sIG4gLSAxLCBpLCAxKTsKICAgICAgICBiZXN0ID0gc3RkOjptaW4oYmVzdCwgbiAtIGkpOwogICAgICB9CiAgICB9CiAgfQoKICBmb3IgKGkgPSAxOyBpIDw9IG4gLSAyOyBpKyspIHsKICAgIGZvciAoaW50IGlpID0gMDsgaWkgPCBNQVhfTjsgaWkrKykgewogICAgICBzZWdbaWkgKiAyXSA9IDA7CiAgICAgIHNlZ1tpaSAqIDIgKyAxXSA9IDA7CiAgICB9CiAgICB1cGRhdGUobiwgbiAtIDEsIGRwW2ldW24gLSAxXSk7CiAgICBmb3IgKGogPSBuIC0gMjsgaiA+PSBpOyBqLS0pIHsKICAgICAgLy8gV2UgcmVtb3ZlZCBvbiB0aGUgcmlnaHQKICAgICAgaWYgKHNbaV0gPT0gc1tqICsgMV0pIHsKICAgICAgICAvLyBXZSBhcmUgYm91bmQgYnkgaGFsZiB0aGUgY3VycmVudCByYW5nZQogICAgICAgIGxvbmdlc3QgPSBzdGQ6Om1pbihqIC0gaSArIDEsIG1baV1baiArIDFdWzFdKTsKICAgICAgICAvL2ZvciAoaz1qKzE7IGs8PWorbG9uZ2VzdDsgaysrKQogICAgICAgIC8vZHBbaV1bal0gfD0gZHBbaV1ba107CiAgICAgICAgaWYgKHF1ZXJ5KG4sIGogKyAxLCBqICsgbG9uZ2VzdCArIDEpKSB7CiAgICAgICAgICBkcFtpXVtqXSA9IDE7CiAgICAgICAgICB1cGRhdGUobiwgaiwgMSk7CiAgICAgICAgICB1cGRhdGVMKG4sIGosIGksIDEpOwogICAgICAgIH0KICAgICAgfQogICAgICAvLyBXZSByZW1vdmVkIG9uIHRoZSBsZWZ0CiAgICAgIGlmIChzW2kgLSAxXSA9PSBzW2pdKSB7CiAgICAgICAgLy8gV2UgYXJlIGJvdW5kIGJ5IGhhbGYgdGhlIGN1cnJlbnQgcmFuZ2UKICAgICAgICBsb25nZXN0ID0gc3RkOjptaW4oaiAtIGkgKyAxLCBtW2kgLSAxXVtqXVswXSk7CiAgICAgICAgLy9mb3IgKGs9aS0xOyBrPj1pLWxvbmdlc3Q7IGstLSkKICAgICAgICAvL2RwW2ldW2pdIHw9IGRwW2tdW2pdOwogICAgICAgIGlmIChxdWVyeUwobiwgaiwgaSAtIGxvbmdlc3QsIGkpKSB7CiAgICAgICAgICBkcFtpXVtqXSA9IDE7CiAgICAgICAgICB1cGRhdGVMKG4sIGosIGksIDEpOwogICAgICAgICAgdXBkYXRlKG4sIGosIDEpOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZHBbaV1bal0pCiAgICAgICAgYmVzdCA9IHN0ZDo6bWluKGJlc3QsIGogLSBpICsgMSk7CiAgICB9CiAgfQp9CgppbnQgc28oc3RyaW5nIHMpIHsKICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9OOyBpKyspIHsKICAgIHNlZ1tpICogMl0gPSAwOwogICAgc2VnW2kgKiAyICsgMV0gPSAwOwogICAgZm9yIChpbnQgaiA9IDA7IGogPCBNQVhfTjsgaisrKSB7CiAgICAgIHNlZ3NMW2ldW2ogKiAyXSA9IDA7CiAgICAgIHNlZ3NMW2ldW2ogKiAyICsgMV0gPSAwOwogICAgICBtW2ldW2pdWzBdID0gMDsKICAgICAgbVtpXVtqXVsxXSA9IDA7CiAgICAgIGRwW2ldW2pdID0gMDsKICAgIH0KICB9CiAgaW50IG4gPSBzLmxlbmd0aCgpOwogIGJlc3QgPSBuOwogIHByZWNhbGMobiwgcyk7CiAgZihuLCBzKTsKICByZXR1cm4gYmVzdDsKfQovLyBFbmQgY29kZSBieSDXktec16LXkyDXkdeo16fXnwoKLy8gQ29kZSBieSBCYW5hbm9uICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKaW50IHJlc3VsdDsKCmludCBscHNbTUFYX05dW01BWF9OXTsKYm9vbCBjaGVja2VkW01BWF9OXVtNQVhfTl07Cgp2b2lkIGNoZWNrKGludCBzdGFydCwgaW50IGxlbmd0aCkgewogIGNoZWNrZWRbc3RhcnRdW2xlbmd0aF0gPSB0cnVlOwogIGlmIChsZW5ndGggPCByZXN1bHQpIHsKICAgIHJlc3VsdCA9IGxlbmd0aDsKICB9CiAgZm9yIChpbnQgaSA9IGxwc1tzdGFydF1bbGVuZ3RoXTsgaSAhPSAwOyBpID0gbHBzW3N0YXJ0XVtpIC0gMV0pIHsKICAgIGludCBuZXdMZW5ndGggPSBsZW5ndGggLSBpOwogICAgaWYgKCFjaGVja2VkW3N0YXJ0XVtuZXdMZW5ndGhdKQogICAgICBjaGVjayhzdGFydCwgbmV3TGVuZ3RoKTsKICAgIGludCBuZXdTdGFydCA9IHN0YXJ0ICsgaTsKICAgIGlmICghY2hlY2tlZFtuZXdTdGFydF1bbmV3TGVuZ3RoXSkKICAgICAgY2hlY2sobmV3U3RhcnQsIG5ld0xlbmd0aCk7CiAgfQp9CgppbnQgbXkoc3RyaW5nIHN0cikgewogIGludCBuID0gc3RyLmxlbmd0aCgpOwogIGZvciAoaW50IGwgPSAwOyBsIDwgbjsgbCsrKSB7CiAgICBpbnQgc3ViTGVuZ3RoID0gbiAtIGw7CiAgICBscHNbbF1bMF0gPSAwOwogICAgY2hlY2tlZFtsXVswXSA9IGZhbHNlOwogICAgZm9yIChpbnQgaSA9IDE7IGkgPCBzdWJMZW5ndGg7ICsraSkgewogICAgICBpbnQgaiA9IGxwc1tsXVtpIC0gMV07CiAgICAgIHdoaWxlIChqID4gMCAmJiBzdHJbaSArIGxdICE9IHN0cltqICsgbF0pCiAgICAgICAgaiA9IGxwc1tsXVtqIC0gMV07CiAgICAgIGlmIChzdHJbaSArIGxdID09IHN0cltqICsgbF0pIGorKzsKICAgICAgbHBzW2xdW2ldID0gajsKICAgICAgY2hlY2tlZFtsXVtpXSA9IGZhbHNlOwogICAgfQogIH0KICByZXN1bHQgPSBuIC0gMTsKICBjaGVjaygwLCBuIC0gMSk7CiAgcmV0dXJuIHJlc3VsdCArIDE7Cn0KCi8vIGdlbmVyYXRlID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgpib29sIHJuZEJvb2woKSB7CiAgcmV0dXJuIHJhbmQoKSAlIDIgPT0gMDsKfQoKaW50IHJuZChpbnQgYm91bmQpIHsKICByZXR1cm4gcmFuZCgpICUgYm91bmQ7Cn0KCnZvaWQgdW50cmltKHN0cmluZyAmIHN0cikgewogIGludCBsZW5ndGggPSBybmQoc3RyLmxlbmd0aCgpKTsKICBpbnQgcHJlZml4TGVuZ3RoID0gcm5kKHN0ci5sZW5ndGgoKSkgKyAxOwogIGlmIChybmRCb29sKCkpCiAgICBzdHIuYXBwZW5kKHN0ci5zdWJzdHIoMCwgcHJlZml4TGVuZ3RoKSk7CiAgZWxzZSB7CiAgICBzdHJpbmcgbmV3U3RyID0gc3RyLnN1YnN0cihzdHIubGVuZ3RoKCkgLSBwcmVmaXhMZW5ndGgsIHByZWZpeExlbmd0aCk7CiAgICBuZXdTdHIuYXBwZW5kKHN0cik7CiAgICBzdHIgPSBuZXdTdHI7CiAgfQp9Cgp2b2lkIHJuZFRlc3QoaW50IG1pblRlc3RMZW5ndGgsIHN0cmluZyBzKSB7CiAgd2hpbGUgKHMubGVuZ3RoKCkgPCBtaW5UZXN0TGVuZ3RoKQogICAgdW50cmltKHMpOwogIGludCBteUFucyA9IG15KHMpOwogIGludCBzb0FucyA9IHNvKHMpOwogIGNvdXQgPDwgbXlBbnMgPDwgIiAiIDw8IHNvQW5zIDw8ICdcbic7CiAgaWYgKHNvQW5zICE9IG15QW5zKSB7CiAgICBjb3V0IDw8IHM7CiAgICBleGl0KDApOwogIH0KfQoKaW50IG1haW4oKSB7CiAgaW50IG1pblRlc3RMZW5ndGg7CiAgY2luID4+IG1pblRlc3RMZW5ndGg7CiAgc3RyaW5nIHNlZWQ7CiAgY2luID4+IHNlZWQ7CiAgd2hpbGUgKHRydWUpCiAgICBybmRUZXN0KG1pblRlc3RMZW5ndGgsIHNlZWQpOwp9