#include <bits/stdc++.h>
using namespace std;
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (T &i : v) is >> i;
  return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
  std::string s;
  is >> s;
  __int128_t ret = 0;
  for (int i = 0; i < s.length(); i++)
    if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
  a = ret * (s[0] == '-' ? -1 : 1);
  return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) {
  std::cin >> p;
}
template <class T>
void scan(std::vector<T> &a) {
  std::cin >> a;
}
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &...tail) {
  scan(head);
  INPUT(tail...);
}
}  // namespace scanner
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
  for (int i = 0; i < int(a.size()); ++i) {
    if (i) os << " ";
    os << a[i];
  }
  return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
  std::ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = std::end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = std::end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(std::ios_base::badbit);
    }
  }
  return dest;
}
template <class T>
void print(const T a) {
  std::cout << a << '\n';
}
template <class Head, class... Tail>
void print(Head H, Tail... T) {
  std::cout << H << ' ';
  print(T...);
}
template <class T>
void printel(const T a) {
  std::cout << a << '\n';
}
template <class T>
void printel(const std::vector<T> &a) {
  for (const auto &v : a) std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
  std::cout << H << '\n';
  printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "NO\n"; }
void err(const bool b = true) {
  if (b) {
    std::cout << "-1\n", exit(0);
  }
}
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
  std::cerr << "{ ";
  for (const auto &v : a) {
    std::cerr << v << ", ";
  }
  std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
  std::cerr << "{\n";
  for (const auto &v : a) {
    std::cerr << "\t";
    view(v);
    std::cerr << "\n";
  }
  std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
  std::cerr << "{\n";
  for (const auto &p : a)
    std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
  std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
  std::cerr << "{\n";
  for (const auto &p : m)
    std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
  std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) {
  std::cerr << "(" << p.first << ", " << p.second << ")";
}
template <class T>
void view(const std::set<T> &s) {
  std::cerr << "{ ";
  for (auto &v : s) {
    view(v);
    std::cerr << ", ";
  }
  std::cerr << "\b\b }";
}
template <class T>
void view(const T &e) {
  std::cerr << e;
}
}  // namespace debugger
template <class T>
int lb(const std::vector<T> &a, const T x) {
  return std::distance((a).begin(),
                       std::lower_bound((a).begin(), (a).end(), (x)));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
  return std::distance((a).begin(),
                       std::upper_bound((a).begin(), (a).end(), (x)));
}
template <class T>
void UNIQUE(std::vector<T> &a) {
  std::sort(a.begin(), a.end());
  a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
  auto res = a;
  UNIQUE(res);
  for (auto &v : a) v = lb(res, v);
  return res;
}
template <class T>
void ADD(std::vector<T> &a, const T x) {
  for (auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
  for (auto &v : a) v -= x;
}
template <class T>
void MUL(std::vector<T> &a, const T x) {
  for (auto &v : a) v *= x;
}
template <class T>
void DIV(std::vector<T> &a, const T x) {
  for (auto &v : a) v /= x;
}
template <class T, class U>
inline bool chmin(T &a, const U &b) {
  return a > b ? a = b, true : false;
}
template <class T, class U>
inline bool chmax(T &a, const U &b) {
  return a < b ? a = b, true : false;
}
template <class T>
T divup(T x, T y) {
  return (x + y - 1) / y;
}
template <class T>
T POW(T a, long long n) {
  T ret = 1;
  while (n) {
    if (n & 1) ret *= a;
    a *= a;
    n >>= 1;
  }
  return ret;
}
long long POW(long long a, long long n, const int mod) {
  long long ret = 1;
  a = (a % mod + mod) % mod;
  while (n) {
    if (n & 1) (ret *= a) %= mod;
    (a *= a) %= mod;
    n >>= 1;
  }
  return ret;
}
struct fast_io {
  fast_io() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
  }
} fast_io_;
const int inf = 1e9;
const ll INF = 1e18;
void main_() {
  int n;
  scanner::INPUT(n);
  if (n <= 3) {
    string res(n, 'a');
    for (int i = 1; i <= (n); ++i) {
      cout << "? " << i << " " << i << endl;
      char s;
      scanner::INPUT(s);
      res[i - 1] = s;
    }
    cout << "! " << res << endl;
    return;
  }
  int x = divup(n, 3);
  int m = n - x;
  cout << "? " << 1 << " " << m << endl;
  multiset<string> st;
  for (int i = 0; i < (m * (m + 1) / 2); ++i) {
    std::string s;
    scanner::INPUT(s);
    std::sort((s).begin(), (s).end());
    st.insert(s);
  }
  cout << "? " << 2 << " " << m << endl;
  for (int i = 0; i < (m * (m - 1) / 2); ++i) {
    std::string s;
    scanner::INPUT(s);
    std::sort((s).begin(), (s).end());
    st.erase(st.find(s));
  }
  VV<> cnt(m + 1, V<>(26));
  for (auto v : st) {
    for (auto &c : v) {
      cnt[((int)(v).size())][c - 'a']++;
    }
  }
  string res(n, 'a');
  for (int i = 0; i < (m); ++i) {
    auto cop = cnt[i + 1];
    for (int j = 0; j < (26); ++j) {
      cop[j] -= cnt[i][j];
      if (cop[j]) {
        res[i] = char('a' + j);
        break;
      }
    }
  }
  cout << "? " << n - 2 * x + 1 << " " << n << endl;
  {
    int k = 2 * x;
    VV<> cnt(k + 1, V<>(26));
    for (int i = 0; i < (k * (k + 1) / 2); ++i) {
      std::string s;
      scanner::INPUT(s);
      for (auto &c : s) cnt[((int)(s).size())][c - 'a']++;
    }
    VV<> add(k + 1, V<>(k));
    for (int i = 0; i < (k); ++i) {
      for (int j = (i); j < (k); ++j) {
        for (int x = (i); x < (j + 1); ++x) {
          add[j - i + 1][x]++;
        }
      }
    }
    int c = 0;
    for (int i = (2); i < (x + 1); ++i) {
      int M = *max_element((add[i]).begin(), (add[i]).end());
      (void(0));
      for (int j = 0; j < (x); ++j) {
        (void(0));
        if (add[i][j] < M) {
          cnt[i][res[n - 2 * x + j] - 'a'] += M - add[i][j];
        }
      }
      for (int j = (k - c); j < (k); ++j) {
        (void(0));
        if (add[i][j] < M) {
          cnt[i][res[n - 2 * x + j] - 'a'] += M - add[i][j];
        }
      }
      for (int j = 0; j < (26); ++j) {
        if (cnt[i][j] % M) {
          res[n - 1 - c] = char('a' + j);
          break;
        }
      }
      c++;
    }
    int z = n - x;
    for (int i = (n - 2 * x); i < (n); ++i) {
      if (i != z) cnt[1][res[i] - 'a']--;
    }
    for (int i = 0; i < (26); ++i) {
      if (cnt[1][i]) {
        res[z] = char('a' + i);
        break;
      }
    }
  }
  cout << "! ";
  print(res);
  cout << endl;
}
int main() {
  int t = 1;
  while (t--) main_();
  return 0;
}
