#pragma GCC optimize("Ofast", "unroll-loops", "no-stack-protector")

#include <bits/stdc++.h>

using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()

using ll = long long;
using ld = double;
using pii = pair<int, int>;
using uint = unsigned int;
using ull = unsigned long long;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
default_random_engine generator;

void solve();

int main() {
#ifdef LOCAL
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);  
#endif 
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << setprecision(16) << fixed;
    cerr << setprecision(16) << fixed;

    int tests = 1;
    // cin >> tests;

    for (int test = 1; test <= tests; ++test) {
        // cout << "Case #" << test << ": ";
        solve();
    }

#ifdef LOCAL
    cerr << "Time: " << double(clock()) / CLOCKS_PER_SEC << endl;
#endif
}

// -----------------------------------------------------------------

const bool TEST = false;

vector<char> ch;

void precalc() {
    // ch = {'0', '1'};

    for (char c = 'A'; c <= 'Z'; ++c) {
        ch.push_back(c);
    }
    for (char c = 'a'; c <= 'z'; ++c) {
        ch.push_back(c);
    }
    for (char c = '0'; c <= '9'; ++c) {
        ch.push_back(c);
    }
}

int n = 128;

string cor;

void gen() {
    int len = rnd() % 128 + 1;
    cor = "";
    for (int i = 0; i < len; ++i) {
        cor += ch[rnd() % sz(ch)];
    }
    cerr << len << endl;
    cerr << cor << endl;
}

int dist(const string &s, const string &t) {
    int n = sz(s);
    int m = sz(t);
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));

    for (int i = 0; i < n; ++i) {
        dp[i + 1][0] = i + 1;
    }
    for (int j = 0; j < m; ++j) {
        dp[0][j + 1] = j + 1;
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (s[i] == t[j]) {
                dp[i + 1][j + 1] = min({dp[i][j + 1] + 1, dp[i + 1][j] + 1, dp[i][j]});
            } else {
                dp[i + 1][j + 1] = min({dp[i][j + 1], dp[i + 1][j], dp[i][j]}) + 1;
            }
        }
    }

    return dp[n][m];
}

int counter = 0;

int ask(const string &s) {
    ++counter;
    assert(counter < 800);

    if (TEST) {
        return dist(s, cor);
    }

    cout << "? " << s << endl;
    int x;
    cin >> x;
    return x;
}

string unite(const string &s, const string &t) {
    string res = s;

    for (int i = 0, ps = 0; i < sz(t); ++i) {
        while (true) {
            string q = res.substr(0, ps);
            q += t[i];
            q += res.substr(ps, sz(res) - ps);
            if (ask(q) == n - sz(q)) {
                res = q;
                ++ps;
                break;
            } else {
                ++ps;
            }
        }
    }

    return res;
}

void solve() {
    precalc();
    
    if (TEST) {
        gen();
    }

    int k = sz(ch);

    vector<int> cnt(k);
    for (int i = 0; i < k; ++i) {
        string s;
        for (int j = 0; j < n; ++j) {
            s += ch[i];
        }
        cnt[i] = n - ask(s);
    }

    vector<string> str;

    int sum = 0;
    for (int i = 0; i < k; ++i) {
        sum += cnt[i];
    }
    n = sum;

    for (int i = 0; i < k; ++i) {
        if (cnt[i] == 0) {
            continue;
        }
        string s;
        for (int j = 0; j < cnt[i]; ++j) {
            s += ch[i];
        }
        str.push_back(s);
    }


    while (sz(str) > 1) {
        sort(all(str), [](const string &s, const string &t) {
            return sz(s) < sz(t);
        });

        string s = str[0];
        string t = str[1];
        reverse(all(str));
        str.pop_back();
        str.pop_back();

        str.push_back(unite(s, t));
    }

    cout << "! " << str[0] << endl;

}   


Measured memory_bytes: 3804