#include <bits/stdc++.h>
using namespace std;
const long long oo = 1e18;
const long long MAXN = 110;
long long N;
vector<string> query(long long a, long long b) {
  cout << "?"
       << " " << a << " " << b << '\n';
  fflush(stdout);
  long long sz = b - a + 1;
  vector<string> vect;
  for (long long i = 0; i < sz * (sz + 1) / 2; i++) {
    string cad;
    cin >> cad;
    vect.push_back(cad);
  }
  return vect;
}
void res(string cad) {
  cout << "!"
       << " " << cad << '\n';
  fflush(stdout);
}
struct edge {
  long long nodo;
  char a, b;
};
vector<edge> L[MAXN];
char xx, yy;
void solve(vector<string> vect, long long des) {
  vector<string> arr[MAXN];
  long long sz = 0;
  for (long long i = 0; i < vect.size(); i++) {
    arr[vect[i].size()].push_back(vect[i]);
    sz = max(sz, (long long)vect[i].size());
  }
  map<char, long long> cont;
  for (long long i = 0; i < sz; i++) {
    cont[arr[sz][0][i]]++;
  }
  vector<edge> vv;
  for (long long i = 2; i <= sz / 2 + 1; i++) {
    map<char, long long> mp;
    map<char, long long> temp;
    for (auto x : cont) {
      temp[x.first] = x.second * i;
    }
    for (long long i = 0; i < vv.size(); i++) {
      temp[vv[i].a] += i + 1;
      temp[vv[i].b] += i + 1;
    }
    for (auto cad : arr[i]) {
      for (long long x = 0; x < i; x++) {
        mp[cad[x]]++;
      }
    }
    char a, b;
    for (auto x : temp) {
      if (x.second > mp[x.first]) {
        a = x.first;
        break;
      }
    }
    temp[a]--;
    for (auto x : temp) {
      if (x.second > mp[x.first]) {
        b = x.first;
        break;
      }
    }
    cont[a]--;
    cont[b]--;
    vv.push_back({0, a, b});
    L[i - 1 + des].push_back({sz - i + 2 + des, a, b});
    L[sz - i + 2 + des].push_back({i - 1 + des, a, b});
    if (i == 2 && des == 0) {
      xx = a;
      yy = b;
    }
  }
}
char ss[MAXN];
void DFS(long long nodo, long long padre, char c) {
  ss[nodo] = c;
  for (auto v : L[nodo]) {
    if (v.nodo != padre) {
      char temp;
      if (v.a == c)
        temp = v.b;
      else
        temp = v.a;
      DFS(v.nodo, nodo, temp);
    }
  }
}
int32_t main() {
  cin >> N;
  vector<string> vect = query(1, N);
  if (N == 1) {
    res(vect[0]);
    return 0;
  }
  solve(vect, 0);
  vect = query(2, N);
  solve(vect, 1);
  if (xx != yy) {
    vect = query(1, 1);
    DFS(1, -1, vect[0][0]);
    string st;
    for (long long i = 1; i <= N; i++) st += ss[i];
    res(st);
  } else {
    DFS(1, -1, xx);
    string st;
    for (long long i = 1; i <= N; i++) st += ss[i];
    for (long long i = 0; i < N; i++) {
      if (st[i] != st[N - i - 1]) {
        vect = query(i + 1, i + 1);
        char cc = vect[0][0];
        if (st[i] != cc) {
          reverse(st.begin(), st.end());
        }
        break;
      }
    }
    res(st);
  }
  return 0;
}
