#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