#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
using namespace std;
template <typename T, typename U>
struct par {
  T x;
  U y;
  par() : x(-1), y(-1) {}
  par(const T& x, const U& y) : x(x), y(y) {}
  bool operator<(const par& other) const {
    if (x == other.x) return y < other.y;
    return x < other.x;
  }
  bool operator==(const par& other) const {
    return x == other.x && y == other.y;
  }
};
template <class T>
inline vector<T> rv(long long n) {
  vector<T> v(n);
  for (long long i = 0; i < (n); i++) cin >> v[i];
  return v;
}
template <class T>
inline void pv(const vector<T>& v) {
  for (long long i = 0; i < (v.size()); i++) cout << v[i] << " ";
  cout << endl;
}
template <class T, class U>
inline void amax(T& a, const U& b) {
  if (a < b) a = b;
}
template <class T, class U>
inline void amin(T& a, const U& b) {
  if (a > b) a = b;
}
const long long MOD = 1e9 + 7;
const long long MOD1 = 998244353;
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }
  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
long long GCD(long long a, long long b) {
  if (a < b) swap(a, b);
  while (b) {
    long long r = a % b;
    a = b;
    b = r;
  }
  return a;
}
vector<string> ask(vector<string>& v) {
  vector<string> ans(3);
  for (int i = 0; i < 3; i++) {
    cout << "? " << v[i] << endl << flush;
    cin >> ans[i];
  }
  return ans;
}
vector<string> ask(vector<string>& v, vector<par<long long, long long> >& sw) {
  vector<string> res(v);
  for (int i = 0; i < sw.size(); i++) {
    for (int j = 0; j < 3; j++) {
      swap(res[j][sw[i].x], res[j][sw[i].y]);
    }
  }
  return res;
}
string solve(const string& s) {
  vector<string> vs(3);
  map<long long, long long> id;
  for (int i = 0; i < s.size(); i++) {
    vs[0].push_back('a' + (i % 26));
  }
  for (int i = 0; i < s.size(); i++) {
    vs[1].push_back(vs[0][i / 26]);
  }
  for (int i = 0; i < s.size(); i++) {
    vs[2].push_back(vs[0][i / (26 * 26)]);
  }
  for (int i = 0; i < s.size(); i++) {
    id[(vs[0][i] - 'a') + 26 * (vs[1][i] - 'a') + 26 * 26 * (vs[2][i] - 'a')] =
        i;
  }
  vector<string> a = ask(vs);
  vector<long long> jd(s.size(), 0);
  for (int i = 0; i < s.size(); i++) {
    jd[i] =
        id[(a[0][i] - 'a') + 26 * (a[1][i] - 'a') + 26 * 26 * (a[2][i] - 'a')];
  }
  string ans(s);
  for (int i = 0; i < s.size(); i++) {
    ans[jd[i]] = s[i];
  }
  return ans;
}
void test() {
  mt19937_64 mt;
  mt.seed(time(0));
  for (;;) {
    string s;
    long long x = 11 + (mt() % 128), y = 11 + (mt() % 67);
    for (long long i = 0; i < x; i++) {
      s += 'a' + (mt() % 26);
    }
    string t(s);
    vector<par<long long, long long> > vs;
    for (long long i = 0; i < y; i++) {
      long long a = mt() % x, b = mt() % x;
      while (a == b) a = mt() % x, b = mt() % x;
      vs.push_back({a, b});
      swap(t[a], t[b]);
    }
    string ans = "";
    if (ans != s) {
      cout << "Expecting ..." << endl
           << s << endl
           << "Got ..." << endl
           << ans << endl;
    }
  }
}
int main(int argc, char** argv) {
  string s;
  cin >> s;
  string t = solve(s);
  cout << "! " << t << endl << flush;
  return 0;
}
