#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
const int MAX = 1e9;
const int PRIME = 1e9+7;
typedef long long ll;
void powers_of_two(int n, vector<int> &t){
int x = 1;
for(int i = 0; i < n; i++){
t.push_back(x);
x *= 2;
}
}
struct _tuple{
int index;
int first;
int second;
_tuple(int index):index(index) {
first = -1;
second = -1;
}
~_tuple(){ }
};
/**
* longest common prefix of two suffixes starting at indexes i and j
* P is defined as in suffix_array
* x initial string
*/
const int d = 22;
vector<int> powers;
int LCP(int i, int j, vector<vector<int>> &P, const string &x){
int n = x.length();
if (i == j) return n-i;
// if (n == 1) return 0;
int nn = static_cast<int>(floor(log2(n)))+1; //next power of two from length of x
int total = 0;
for(int step = nn; step >= 0; step--){
if (i >= n || j >= n) break;
if (P[step][i] == P[step][j]){
total += powers[step];
i += powers[step];
j += powers[step];
}
}
return total;
}
/**
* @param P preliminary result P[i][j] is the rank of suffix at index "j" as compared using first 2^i characters
* @param x actual string
*/
void suffix_array(vector<vector<int>> &P, const string &x){
int n = x.length();
int nn = static_cast<int>(floor(log2(n)))+1 ; //next power of two from length of x
P.resize(nn+1, vector<int>(n, -1));
if (n == 1) {
P[0][0] = 0;
return;
}
vector<_tuple> L(n, _tuple(0));
for(int j = 0; j < n; j++){
P[0][j] = x[j]-'a';
}
for(int i = 1; i <= nn; i++){
for(int j = 0; j < n; j++){
L[j].index = j;
L[j].first = P[i-1][j];
if (j + powers[i-1] < n){
L[j].second = P[i-1][j+powers[i-1]];
}
else L[j].second = -1;
}
sort(L.begin(), L.end(), [](const _tuple &a, const _tuple &b){
return a.first < b.first || (a.first == b.first && a.second < b.second);
});
for(int j = 0; j < n; j++){
if (j == 0){
P[i][L[j].index] = 0;
}
else {
if (L[j].first == L[j-1].first && L[j].second == L[j-1].second){
P[i][L[j].index] = P[i][L[j-1].index];
} else {
P[i][L[j].index] = j;
}
}
}
}
}
int main(int argc, char const *argv[])
{
powers_of_two(d, powers);
string x, orig;
cin >> x;
orig = x;
reverse(x.begin(), x.end());
vector<vector<int>> P;
suffix_array(P, x);
int ans = 0;
for(int i = 1; i < x.length(); i++){
if (LCP(0, i, P, x) >= i) ans = i;
}
cout << orig.substr(orig.length()-ans, ans) << endl;
return 0;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y21hdGg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNvbnN0IGludCBNQVggPSAxZTk7CmNvbnN0IGludCBQUklNRSA9IDFlOSs3Owp0eXBlZGVmIGxvbmcgbG9uZyBsbDsKdm9pZCBwb3dlcnNfb2ZfdHdvKGludCBuLCB2ZWN0b3I8aW50PiAmdCl7CglpbnQgeCA9IDE7Cglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKCQl0LnB1c2hfYmFjayh4KTsKCQl4ICo9IDI7Cgl9Cn0KCnN0cnVjdCBfdHVwbGV7CglpbnQgaW5kZXg7CglpbnQgZmlyc3Q7CglpbnQgc2Vjb25kOwoJX3R1cGxlKGludCBpbmRleCk6aW5kZXgoaW5kZXgpIHsKCQlmaXJzdCA9IC0xOwoJCXNlY29uZCA9IC0xOwoJfQoJfl90dXBsZSgpeyB9Cn07Ci8qKgogKglsb25nZXN0IGNvbW1vbiBwcmVmaXggb2YgdHdvIHN1ZmZpeGVzIHN0YXJ0aW5nIGF0IGluZGV4ZXMgaSBhbmQgagogKglQIGlzIGRlZmluZWQgYXMgaW4gc3VmZml4X2FycmF5CiAqIAl4IGluaXRpYWwgc3RyaW5nCiAqLwoKY29uc3QgaW50IGQgPSAyMjsKCnZlY3RvcjxpbnQ+IHBvd2VyczsKCgoKaW50IExDUChpbnQgaSwgaW50IGosIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gJlAsIGNvbnN0IHN0cmluZyAmeCl7CglpbnQgbiA9IHgubGVuZ3RoKCk7CglpZiAoaSA9PSBqKSByZXR1cm4gbi1pOwoJLy8gaWYgKG4gPT0gMSkgcmV0dXJuIDA7CglpbnQgbm4gPSBzdGF0aWNfY2FzdDxpbnQ+KGZsb29yKGxvZzIobikpKSsxOyAvL25leHQgcG93ZXIgb2YgdHdvIGZyb20gbGVuZ3RoIG9mIHgKCWludCB0b3RhbCA9IDA7Cglmb3IoaW50IHN0ZXAgPSBubjsgc3RlcCA+PSAwOyBzdGVwLS0pewoJCWlmIChpID49IG4gfHwgaiA+PSBuKSBicmVhazsKCQlpZiAoUFtzdGVwXVtpXSA9PSBQW3N0ZXBdW2pdKXsKCQkJdG90YWwgKz0gcG93ZXJzW3N0ZXBdOwoJCQlpICs9IHBvd2Vyc1tzdGVwXTsKCQkJaiArPSBwb3dlcnNbc3RlcF07CgkJfQoJfQoJcmV0dXJuIHRvdGFsOwkKfQoKLyoqCiAqIEBwYXJhbSBQICBwcmVsaW1pbmFyeSByZXN1bHQgUFtpXVtqXSBpcyB0aGUgcmFuayBvZiBzdWZmaXggYXQgaW5kZXggImoiIGFzIGNvbXBhcmVkIHVzaW5nIGZpcnN0IDJeaSBjaGFyYWN0ZXJzCiAqIEBwYXJhbSB4ICBhY3R1YWwgc3RyaW5nCiAqLwp2b2lkIHN1ZmZpeF9hcnJheSh2ZWN0b3I8dmVjdG9yPGludD4+ICZQLCBjb25zdCBzdHJpbmcgJngpewoJaW50IG4gPSB4Lmxlbmd0aCgpOwoJaW50IG5uID0gc3RhdGljX2Nhc3Q8aW50PihmbG9vcihsb2cyKG4pKSkrMSA7IC8vbmV4dCBwb3dlciBvZiB0d28gZnJvbSBsZW5ndGggb2YgeAoJUC5yZXNpemUobm4rMSwgdmVjdG9yPGludD4obiwgLTEpKTsKCWlmIChuID09IDEpIHsKCQlQWzBdWzBdID0gMDsKCQlyZXR1cm47Cgl9Cgl2ZWN0b3I8X3R1cGxlPiBMKG4sIF90dXBsZSgwKSk7Cglmb3IoaW50IGogPSAwOyBqIDwgbjsgaisrKXsKCQlQWzBdW2pdID0geFtqXS0nYSc7Cgl9Cglmb3IoaW50IGkgPSAxOyBpIDw9IG5uOyBpKyspewoJCWZvcihpbnQgaiA9IDA7IGogPCBuOyBqKyspewoJCQlMW2pdLmluZGV4ID0gajsKCQkJTFtqXS5maXJzdCA9IFBbaS0xXVtqXTsKCQkJaWYgKGogKyBwb3dlcnNbaS0xXSA8IG4pewoJCQkJTFtqXS5zZWNvbmQgPSBQW2ktMV1baitwb3dlcnNbaS0xXV07CgkJCX0KCQkJZWxzZSBMW2pdLnNlY29uZCA9IC0xOwoJCX0KCQlzb3J0KEwuYmVnaW4oKSwgTC5lbmQoKSwgW10oY29uc3QgX3R1cGxlICZhLCBjb25zdCBfdHVwbGUgJmIpewoJCQlyZXR1cm4gYS5maXJzdCA8IGIuZmlyc3QgfHwgKGEuZmlyc3QgPT0gYi5maXJzdCAmJiBhLnNlY29uZCA8IGIuc2Vjb25kKTsKCQl9KTsKCQlmb3IoaW50IGogPSAwOyBqIDwgbjsgaisrKXsKCQkJaWYgKGogPT0gMCl7CgkJCQlQW2ldW0xbal0uaW5kZXhdID0gMDsKCQkJfQoJCQllbHNlIHsKCQkJCWlmIChMW2pdLmZpcnN0ID09IExbai0xXS5maXJzdCAmJiBMW2pdLnNlY29uZCA9PSBMW2otMV0uc2Vjb25kKXsKCQkJCQlQW2ldW0xbal0uaW5kZXhdID0gUFtpXVtMW2otMV0uaW5kZXhdOwoJCQkJfSBlbHNlIHsKCQkJCQlQW2ldW0xbal0uaW5kZXhdID0gajsKCQkJCX0KCQkJfQoJCX0KCX0KfQoKCmludCBtYWluKGludCBhcmdjLCBjaGFyIGNvbnN0ICphcmd2W10pCnsKCXBvd2Vyc19vZl90d28oZCwgcG93ZXJzKTsKCXN0cmluZyB4LCBvcmlnOwoJY2luID4+IHg7CglvcmlnID0geDsKCXJldmVyc2UoeC5iZWdpbigpLCB4LmVuZCgpKTsKCXZlY3Rvcjx2ZWN0b3I8aW50Pj4gUDsKCXN1ZmZpeF9hcnJheShQLCB4KTsKCWludCBhbnMgPSAwOwoJZm9yKGludCBpID0gMTsgaSA8IHgubGVuZ3RoKCk7IGkrKyl7CgkJaWYgKExDUCgwLCBpLCBQLCB4KSA+PSBpKSBhbnMgPSBpOwoJfQoJY291dCA8PCBvcmlnLnN1YnN0cihvcmlnLmxlbmd0aCgpLWFucywgYW5zKSA8PCBlbmRsOwoJcmV0dXJuIDA7Cn0K