#include <bits/stdc++.h>

#define itn int
#define all(x) (x).begin(), (x).end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())

#define random_shuffle(...) shuffle(__VA_ARGS__, rng)
#define rand() rng()

#ifdef OLBOEB
	#define return std::cerr << __FUNCTION__ << "\n"; return
#endif  // OLBOEB

using namespace std;

inline int nxt() {
	int x;
	// scanf("%d", &x);
	cin >> x;
	return x;
}

struct Info {
	int choose;
	int conseq;
};

Info operator -(const Info& fst, const Info& snd) {
	return {fst.choose - snd.choose, fst.conseq - snd.conseq};
}

Info readInfo() {
	int x = nxt(), y = nxt();
	return {x, y};
}

Info initial;
Info last;
Info delta;
vector<Info> history;

void ask(int pos) {
	cout << "+ " << pos + 1 << endl;
	Info fresh = readInfo();
	history.push_back(delta = fresh - last);
	last = fresh;
}

map<int, int> by_choose;

int main() {
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

	for (int i = 1; i < 1000; ++i) {
		by_choose[i * (i - 1) / 2] = i;
	}

	int n = nxt();
	last = initial = readInfo();
	vector<int> ans(n, -1);
	vector<int> a(n, -1);

	ask(0);
	if (delta.choose) {
		ans[0] = by_choose[delta.choose];
		a[0] = ans[0] + 1;
	}
	bool is_zero_among_12 = (delta.conseq == 0);
	ask(1);
	if (initial.conseq == last.conseq) {
		ans[2] = a[2] = 0;
	}
	if (delta.choose) {
		ans[1] = by_choose[delta.choose];
		a[1] = ans[1] + 1;
	}

	bool is_2_pressed = false;
	if (a[0] == -1 && a[1] == -1) {
		if (!is_zero_among_12) {
			ans[1] = 1;
			a[1] = 2;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
		} else if (a[2] != 0) {
			ans[1] = 0;
			a[1] = 1;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
		} else {
			ask(2);
			a[2] = 1;
			int conseq_after_2 = delta.conseq;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
			a[1] = delta.conseq;
			ans[1] = a[1] - 1;
			if (conseq_after_2 == (a[0] - 1) * a[1]) {
				ans[3] = a[3] = 0;
			}
			is_2_pressed = true;
		}
	} else if (a[0] == -1) {
		ask(0);
		ans[0] = by_choose[delta.choose] - 1;
		a[0] = ans[0] + 2;
	} else if (a[1] == -1) {
		ask(1);
		ans[1] = by_choose[delta.choose] - 1;
		a[1] = ans[1] + 2;
	}

	for (int i = (is_2_pressed ? 3 : 2); i < n - 1; ++i) {
		if (a[i] == 0) {
			ask(i);
			++a[i];
		} else {
			ask(i);
			ans[i] = by_choose[delta.choose];
			a[i] = ans[i] + 1;
		}
		if (delta.conseq == a[i - 2] * a[i - 1]) {
			ans[i + 1] = a[i + 1] = 0;
		}
	}

	ans[n - 1] = a[n - 1] = (delta.conseq - a[n - 3] * a[n - 4]) / a[n - 3];
	cout << "!";
	for (int x : ans) {
		cout << " " << x;
	}
	cout << endl;

	return 0;
}


#include <bits/stdc++.h>

#define itn int
#define all(x) (x).begin(), (x).end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())

#define random_shuffle(...) shuffle(__VA_ARGS__, rng)
#define rand() rng()

#ifdef OLBOEB
	#define return std::cerr << __FUNCTION__ << "\n"; return
#endif  // OLBOEB

using namespace std;

inline int nxt() {
	int x;
	// scanf("%d", &x);
	cin >> x;
	return x;
}

struct Info {
	int choose;
	int conseq;
};

Info operator -(const Info& fst, const Info& snd) {
	return {fst.choose - snd.choose, fst.conseq - snd.conseq};
}

Info readInfo() {
	int x = nxt(), y = nxt();
	return {x, y};
}

Info initial;
Info last;
Info delta;
vector<Info> history;

void ask(int pos) {
	cout << pos + 1 << endl;
	Info fresh = readInfo();
	history.push_back(delta = fresh - last);
	last = fresh;
}

map<int, int> by_choose;

int main() {
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

	for (int i = 1; i < 1000; ++i) {
		by_choose[i * (i - 1) / 2] = i;
	}

	int n = nxt();
	last = initial = readInfo();
	vector<int> ans(n, -1);
	vector<int> a(n, -1);

	ask(0);
	if (delta.choose) {
		ans[0] = by_choose[delta.choose];
		a[0] = ans[0] + 1;
	}
	bool is_zero_among_12 = (delta.conseq == 0);
	ask(1);
	if (initial.conseq == last.conseq) {
		ans[2] = a[2] = 0;
	}
	if (delta.choose) {
		ans[1] = by_choose[delta.choose];
		a[1] = ans[1] + 1;
	}

	bool is_2_pressed = false;
	if (a[0] == -1 && a[1] == -1) {
		if (!is_zero_among_12) {
			ans[1] = 1;
			a[1] = 2;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
		} else if (a[2] != 0) {
			ans[1] = 0;
			a[1] = 1;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
		} else {
			ask(2);
			a[2] = 1;
			int conseq_after_2 = delta.conseq;
			ask(0);
			ans[0] = by_choose[delta.choose] - 1;
			a[0] = ans[0] + 1;
			a[1] = delta.conseq;
			ans[1] = a[1] - 1;
			if (conseq_after_2 == (a[0] - 1) * a[1]) {
				ans[3] = a[3] = 0;
			}
			is_2_pressed = true;
		}
	} else if (a[0] == -1) {
		ask(0);
		ans[0] = by_choose[delta.choose] - 1;
		a[0] = ans[0] + 2;
	} else if (a[1] == -1) {
		ask(1);
		ans[1] = by_choose[delta.choose] - 1;
		a[1] = ans[1] + 2;
	}

	for (int i = (is_2_pressed ? 3 : 2); i < n - 1; ++i) {
		if (a[i] == 0) {
			ask(i);
			++a[i];
		} else {
			ask(i);
			ans[i] = by_choose[delta.choose];
			a[i] = ans[i] + 1;
		}
		if (delta.conseq == a[i - 2] * a[i - 1]) {
			ans[i + 1] = a[i + 1] = 0;
		}
	}

	ans[n - 1] = a[n - 1] = (delta.conseq - a[n - 3] * a[n - 4]) / a[n - 3];
	cout << "!";
	for (int x : ans) {
		cout << " " << x;
	}
	cout << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 110;

int N;
int ttot, stot;
int cnt[MAXN];

pair <int, int> ask (int x)
{
    cout << "+ " << x + 1 << endl << flush;
    int tnew, snew;
    cin >> tnew >> snew;

    pair <int, int> res = make_pair (tnew - ttot, snew - stot);
    ttot = tnew;
    stot = snew;
    return res;
}

int gf (int x)
{
    // just added 1 and x new trips
    int res = 2;
    while ((res - 1) * (res - 2) / 2 < x)
        res++;
    return res;
}

int main()
{
    ios_base::sync_with_stdio(0);

    cin >> N >> ttot >> stot;

    pair <int, int> p1 = ask (0);
    pair <int, int> p2 = ask (1);
    pair <int, int> p3 = ask (2);
    pair <int, int> p4 = ask (0);

    cnt[0] = gf (p4.first);
    if (p2.second)
        cnt[2] = gf (p3.first);
    else
        cnt[2] = 1;
    cnt[1] = p4.second / cnt[2];

    int nnext = p3.second - (cnt[0] - 1) * cnt[1];
    for (int i = 3; i < N - 1; i++)
    {
        pair <int, int> np = ask (i);
        if (nnext == 0) cnt[i] = 0;
        else cnt[i] = gf (np.first);
        nnext = np.second - cnt[i-2] * cnt[i-1];
    }
    cnt[N-1] = nnext / cnt[N-3];

    cout << "!";
    for (int i = 0; i < N; i++)
    {
        cout << " ";

        if (i == 0) cout << cnt[i] - 2;
        else if (i == N - 1) cout << cnt[i];
        else cout << cnt[i] - 1;
    }
    cout << "\n";
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 110;

int N;
int ttot, stot;
int cnt[MAXN];

pair <int, int> ask (int x)
{
    cout << "+ " << x + 1 << endl << flush;
    int tnew, snew;
    cin >> tnew >> snew;

    pair <int, int> res = make_pair (tnew - ttot, snew - stot);
    ttot = tnew;
    stot = snew;
    return res;
}

int gf (int x)
{
    // just added 1 and x new trips
    int res = 2;
    while ((res - 1) * (res - 2) / 2 < x)
        res++;
    return res;
}

int main()
{
    ios_base::sync_with_stdio(0);

    cin >> N >> ttot >> stot;

    pair <int, int> p1 = ask (0);
    pair <int, int> p2 = ask (1);
    pair <int, int> p3 = ask (2);
    pair <int, int> p4 = ask (0);

    cnt[0] = gf (p4.first);
    if (p2.second)
        cnt[2] = gf (p3.first);
    else
        cnt[2] = 1;
    cnt[1] = p4.second / cnt[2];

    int nnext = p3.second - (cnt[0] - 1) * cnt[1];
    for (int i = 3; i < N - 1; i++)
    {
        pair <int, int> np = ask (i);
        if (nnext == 0) cnt[i] = 1;
        else cnt[i] = gf (np.first);
        nnext = np.second - cnt[i-2] * cnt[i-1];
    }
    cnt[N-1] = nnext / cnt[N-3];

    cout << "!";
    for (int i = 0; i < N; i++)
    {
        cout << " ";

        if (i == 0) cout << cnt[i] - 2;
        else if (i == N - 1) cout << cnt[i];
        else cout << cnt[i] - 1;
    }
    cout << "\n";
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 110;

int N;
int ttot, stot;
int cnt[MAXN];

pair <int, int> ask (int x)
{
    cout << "+ " << x + 1 << endl << flush;
    int tnew, snew;
    cin >> tnew >> snew;

    pair <int, int> res = make_pair (tnew - ttot, snew - stot);
    ttot = tnew;
    stot = snew;
    return res;
}

int gf (int x)
{
    // just added 1 and x new trips
    int res = 2;
    while ((res - 1) * (res - 2) / 2 < x)
        res++;
    return res;
}

int main()
{
    ios_base::sync_with_stdio(0);

    cin >> N >> ttot >> stot;

    pair <int, int> p1 = ask (0);
    pair <int, int> p2 = ask (1);
    pair <int, int> p3 = ask (2);
    pair <int, int> p4 = ask (0);

    cnt[0] = gf (p4.first);
    if (p2.second)
        cnt[2] = gf (p3.first);
    else
        cnt[2] = 1;
    cnt[1] = p4.second / cnt[2];

    int nnext = p3.second - (cnt[0] - 1) * cnt[1];
    for (int i = 3; i < N - 1; i++)
    {
        pair <int, int> np = ask (i);
        if (nnext == 0) cnt[i] = 0;
        else cnt[i] = gf (np.first);
        nnext = np.second - cnt[i-2] * cnt[i-1];
    }
    cnt[N-1] = nnext / cnt[N-3];

    for (int i = 0; i < N; i++)
    {
        if (i) cout << " ";

        if (i == 0) cout << cnt[i] - 2;
        else if (i == N - 1) cout << cnt[i];
        else cout << cnt[i] - 1;
    }
    cout << "\n";
}


#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  long long X, Y;
  cin >> X >> Y;
  vector<int> qs(n);
  auto Ask = [&](int i) {
    qs[i] += 1;
    cout << "+ " << i + 1 << endl;
    long long x, y;
    cin >> x >> y;
    auto p = make_pair(x - X, y - Y);
    X = x;
    Y = y;
    return p;
  };
  long long a, b, c, d;
  long long e = -1;
  auto p0 = Ask(1);
  if (p0.second != 0) {
    auto p1 = Ask(0);
    auto p2 = Ask(1);
    auto p3 = Ask(0);
    c = p2.second - p0.second;
    b = p1.second / c - 1;
    a = 0;
    while (a * (a + 1) / 2 != p3.first) {
      ++a;
    }
    d = p0.second / c - a;
  } else {
    auto p1 = Ask(2);
    if (p1.second != 0) {
      auto p2 = Ask(0);
      auto p3 = Ask(0);
      a = 0;
      while (a * (a + 1) / 2 != p3.first) {
        ++a;
      }
      c = 0;
      b = p2.second - 1;
      long long x = p1.second - (b + 1) * a;
      if (x == 0) {
        d = 0;
      } else {
        if (n == 4) {
          d = x / (b + 1);
        } else {
          auto p4 = Ask(1);
          d = p4.second / (c + 1) - (a + 2);
          e = x / d - (b + 1);
        }
      }
    } else {
      auto p2 = Ask(1);
      auto p3 = Ask(2);
      b = 0;
      while (b * (b + 1) / 2 != p2.first) {
        ++b;
      }
      c = 0;
      while (c * (c + 1) / 2 != p3.first) {
        ++c;
      }
      a = 0;
      d = 0;
    }
  }
  vector<long long> res(n);
  res[0] = a;
  res[1] = b;
  res[2] = c;
  res[3] = d;
  int j = 4;
  if (e != -1) {
    res[4] = e;
    j = 5;
  }
  while (j < n) {
    assert(res[j - 2] + qs[j - 2] != 0);
    if (res[j - 1] + qs[j - 1] != 0) {
      auto p = Ask(j - 2);
      long long u = p.second;
      u -= (res[j - 4] + qs[j - 4]) * (res[j - 3] + qs[j - 3]);
      u -= (res[j - 3] + qs[j - 3]) * (res[j - 1] + qs[j - 1]);
      u /= res[j - 1] + qs[j - 1];
      res[j] = u;
      ++j;
    } else {
        auto p = Ask(j - 1);
        long long u = p.second;
        u -= (res[j - 3] + qs[j - 3]) * (res[j - 2] + qs[j - 2]);
        if (j == n - 1 || u == 0) {
          res[j] = u / (res[j - 2] + qs[j - 2]);
          ++j;
        } else {
          auto q = Ask(j - 2);
          long long v = q.second;
          v -= (res[j - 4] + qs[j - 4]) * (res[j - 3] + qs[j - 3]);
          v -= (res[j - 3] + qs[j - 3]) * (res[j - 1] + qs[j - 1]);
          res[j] = v;
          res[j + 1] = u / v - (res[j - 2] + qs[j - 2] - 1);
          j += 2;
        }
    }
  }
  cout << "!";
  for (int i = 0; i < n; i++) {
    cout << " " << res[i];
  }
  cout << endl;
  return 0;
}


#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int N = 111;
int d_tr[N], d_str[N];
int sure[N];
int fin[N];
int n;
int val[N];
int cur[N];
int GetTr() {
#ifdef LOCAL
  int res = 0;
  RE (i, n) {
    res += (cur[i] * (cur[i] - 1) * (cur[i] - 2)) / 6;
  }
  return res;
#else
  int res;
  cin>>res;
  return res;
#endif
}
int GetStr() {
  int res = 0;
#ifdef LOCAL
  RE (i, n - 2) {
    res += cur[i] * (cur[i + 1] * cur[i + 2]);
  }
#else
  cin>>res;
#endif
  return res;
}

bool Bt(int pos) {

  if (pos == n + 1) {
    return true;
  }
  VI poss;
  if (sure[pos]) {
    poss.PB(sure[pos]);
  } else {
    poss.PB(1);
    poss.PB(2);
  }
  //bool any = false;
  for (auto cand : poss) {
    fin[pos] = cand;
    debug(pos);
    RE (i, pos) {
      cerr<<fin[i]<<" ";
    }
    cerr<<endl;
    bool fail = false;
    if (pos >= 3) {
      int need = (fin[pos] - 1) * (fin[pos - 1] - 1) /** fin[pos - 2]*/;
      if (pos >= 4) {
        need += (fin[pos - 1] - 1) /** fin[pos - 2]*/ * fin[pos - 3];
      }
      if (pos >= 5) {
        need += /*fin[pos - 2] **/ fin[pos - 3] * fin[pos - 4];
      }
      debug(need, d_str[pos - 2]);
      if (need != d_str[pos - 2]) {
        fail = true;
      }
    }
    if (pos == n) {
      if (d_str[n] != /*fin[pos] **/ fin[pos - 1] * fin[pos - 2]) { fail = true;}
      if (d_str[n - 1] != (fin[pos] - 1) /** fin[pos - 1]*/ * fin[pos - 2] + /*fin[pos - 1] **/ fin[pos - 2] * fin[pos - 3]) { fail = true; }
    }
    if (fail) { continue; }
    if (Bt(pos + 1)) {
      return true;
    }
  }
  return false;
}
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;

  cin>>n;
#ifdef LOCAL
  RE (i, n) {
    cin>>cur[i];
  }
#endif
  int tr, str;
  tr = GetTr();
  str = GetStr();
  RE (i, n) {
    cout<<"+ "<<i<<endl;
    cur[i]++;
    int ntr, nstr;
    ntr = GetTr();
    nstr = GetStr();
    d_tr[i] = ntr - tr;
    d_str[i] = nstr - str;
    if (d_tr[i] > 0) {
      debug(d_tr[i]);
      RE (j, n) {
        if ((j - 1) * (j - 2) == 2 * d_tr[i]) {
          sure[i] = j;
          //init[i] = j - 1;
          break;
        }
      }
      assert(sure[i]);
    }
    tr = ntr;
    str = nstr;
  }
  RE (i, n) {
    debug(i, sure[i]);
  }
  assert(Bt(1));
  cout<<"! ";
  RE (i, n) {
    cout<<fin[i] - 1<<" ";
  }
  cout<<endl;

  return 0;
}


#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int N = 111;
int d_tr[N], d_str[N];
int sure[N];
int init[N];
int fin[N];
int n;
int val[N];
int cur[N];
int GetTr() {
#ifdef LOCAL
  int res = 0;
  RE (i, n) {
    res += (cur[i] * (cur[i] - 1) * (cur[i] - 2)) / 6;
  }
  return res;
#else
  int res;
  cin>>res;
  return res;
#endif
}
int GetStr() {
  int res = 0;
#ifdef LOCAL
  RE (i, n - 2) {
    res += cur[i] * (cur[i + 1] * cur[i + 2]);
  }
#else
  cin>>res;
#endif
  return res;
}
int tr, str;
int pref[N][N];
VI asks;
bool Bt(int pos) {

  if (pos == n + 1) {
    RE (i, n) {
      fin[i] = init[i];
    }
    REP (i, n) {
      fin[asks[i]]++;
    }
    int res = 0;
    RE (i, n) {
      res += (fin[i] * (fin[i] - 1) * (fin[i] - 2)) / 6;
    }
    if (res != tr) { return false; }
    res = 0;
    RE (i, n - 2) {
      res += fin[i] * fin[i + 1] * fin[i + 2];
    }
    if (res != str) { return false; }
    return true;
  }
  VI poss;
  if (pref[pos][n - 1] == 0) {
    REP (i, n + 1) {
      poss.PB(i);
    }
  } else if (sure[pos]) {
    poss.PB(sure[pos]);
    REP (i, n) {
      if (asks[i] == pos) {
        poss.back()--;
      }
    }
  } else {
    poss.PB(0);
    poss.PB(1);
  }
  //bool any = false;
  for (auto cand : poss) {
    init[pos] = cand;
    int fail = 0;
    REP (i, n) {
      int a = asks[i];
      if (a <= pos - 2 || pos == n) { // wszystko co potrzebne to juz mam ustalone
        int need = 0;
        if (a >= 3) {
          need += (init[a - 2] + pref[a - 2][i]) * (init[a - 1] + pref[a - 1][i]);
        }
        if (a >= 2) {
          need += (init[a - 1] + pref[a - 1][i]) * (init[a + 1] + pref[a + 1][i]);
        }
        need += (init[a + 1] + pref[a + 1][i]) * (init[a + 2] + pref[a + 2][i]);
        if (need != d_str[i + 1]) { fail = true; }
      }
    }
//     debug(pos);
//     RE (i, pos) {
//       cerr<<fin[i]<<" ";
//     }
//     cerr<<endl;
//     bool fail = false;
//     if (pos >= 3) {
//       int need = (fin[pos] - 1) * (fin[pos - 1] - 1) /** fin[pos - 2]*/;
//       if (pos >= 4) {
//         need += (fin[pos - 1] - 1) /** fin[pos - 2]*/ * fin[pos - 3];
//       }
//       if (pos >= 5) {
//         need += /*fin[pos - 2] **/ fin[pos - 3] * fin[pos - 4];
//       }
//       debug(pos, need, d_str[pos - 2]);
//       if (need != d_str[pos - 2]) {
//         fail = true;
//       }
//     }
//     if (pos == n) {
//       if (d_str[n] != fin[n - 4] * fin[n - 3] + fin[n - 3] * fin[n - 1] + fin[n - 1] * fin[n]) { fail = true;}
//       if (d_str[n - 1] != (fin[pos] - 1) * fin[pos - 2] + fin[pos - 2] * fin[pos - 3]) { fail = true; }
//     }
    if (fail) { continue; }
    if (Bt(pos + 1)) {
      return true;
    }
  }
  return false;
}
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;

  cin>>n;
#ifdef LOCAL
  RE (i, n) {
    cin>>cur[i];
    cerr<<cur[i]<<" ";
  }
  cerr<<endl;
#endif
  //int tr, str;
  tr = GetTr();
  str = GetStr();

  asks.PB(n);
  FOR (i, 2, n) {
    asks.PB(i);
  }
  if (n == 4) {
    asks = {4, 2, 3, 4};
  }
  pref[asks[0]][0] = 1;
  RE (i, n - 1) {
    RE (j, n) {
      pref[j][i] = pref[j][i - 1];
    }
    pref[asks[i]][i]++;
  }
  RE (i, n) {
    debug(i, pref[i][n - 1]);
  }

  RE (i, n) {
//     int ziom = i;
//     if (ziom == n) {
//       ziom = n - 2;
//     } /*else if (ziom == n - 1) {
//       ziom = n;
//     }*/
    cout<<"+ "<<asks[i - 1]<<endl;
    cur[asks[i - 1]]++;
    int ntr, nstr;
    ntr = GetTr();
    nstr = GetStr();
    d_tr[i] = ntr - tr;
    d_str[i] = nstr - str;
    if (d_tr[i] > 0) {
      debug(d_tr[i]);
      RE (j, n) {
        if ((j - 1) * (j - 2) == 2 * d_tr[i]) {
          sure[asks[i - 1]] = j;
          //init[i] = j - 1;
          break;
        }
      }
      assert(sure[asks[i - 1]]);
    }
    tr = ntr;
    str = nstr;
  }
  RE (i, n) {
    debug(i, sure[i]);
  }
  Bt(1);
  cout<<"! ";
  RE (i, n) {
    cout<<init[i]<<" ";
  }
  cout<<endl;
#ifdef LOCAL
  RE (i, n) {
    assert(init[i] + pref[i][n - 1] == cur[i]);
  }
#endif

  return 0;
}


#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int N = 111;
int d_tr[N], d_str[N];
int sure[N];
int init[N];
int fin[N];
int n;
int val[N];
int cur[N];
int GetTr() {
#ifdef LOCAL
  int res = 0;
  RE (i, n) {
    res += (cur[i] * (cur[i] - 1) * (cur[i] - 2)) / 6;
  }
  return res;
#else
  int res;
  cin>>res;
  return res;
#endif
}
int GetStr() {
  int res = 0;
#ifdef LOCAL
  RE (i, n - 2) {
    res += cur[i] * (cur[i + 1] * cur[i + 2]);
  }
#else
  cin>>res;
#endif
  return res;
}
int tr, str;
int pref[N][N];
VI asks;
bool Bt(int pos) {

  if (pos == n + 1) {
    RE (i, n) {
      fin[i] = init[i];
    }
    REP (i, n) {
      fin[asks[i]]++;
    }
    int res = 0;
    RE (i, n) {
      res += (fin[i] * (fin[i] - 1) * (fin[i] - 2)) / 6;
    }
    if (res != tr) { return false; }
    res = 0;
    RE (i, n - 2) {
      res += fin[i] * fin[i + 1] * fin[i + 2];
    }
    if (res != str) { return false; }
    return true;
  }
  VI poss;
  if (pref[pos][n - 1] == 0) {
    REP (i, n + 1) {
      poss.PB(i);
    }
  } else if (sure[pos]) {
    poss.PB(sure[pos]);
    REP (i, n) {
      if (asks[i] == pos) {
        poss.back()--;
      }
    }
  } else {
    poss.PB(0);
    poss.PB(1);
  }
  //bool any = false;
  for (auto cand : poss) {
    init[pos] = cand;
    int fail = 0;
    REP (i, n) {
      int a = asks[i];
      if (a <= pos - 2 || pos == n) { // wszystko co potrzebne to juz mam ustalone
        int need = 0;
        if (a >= 3) {
          need += (init[a - 2] + pref[a - 2][i]) * (init[a - 1] + pref[a - 1][i]);
        }
        if (a >= 2) {
          need += (init[a - 1] + pref[a - 1][i]) * (init[a + 1] + pref[a + 1][i]);
        }
        need += (init[a + 1] + pref[a + 1][i]) * (init[a + 2] + pref[a + 2][i]);
        if (need != d_str[i + 1]) { fail = true; }
      }
    }
//     debug(pos);
//     RE (i, pos) {
//       cerr<<fin[i]<<" ";
//     }
//     cerr<<endl;
//     bool fail = false;
//     if (pos >= 3) {
//       int need = (fin[pos] - 1) * (fin[pos - 1] - 1) /** fin[pos - 2]*/;
//       if (pos >= 4) {
//         need += (fin[pos - 1] - 1) /** fin[pos - 2]*/ * fin[pos - 3];
//       }
//       if (pos >= 5) {
//         need += /*fin[pos - 2] **/ fin[pos - 3] * fin[pos - 4];
//       }
//       debug(pos, need, d_str[pos - 2]);
//       if (need != d_str[pos - 2]) {
//         fail = true;
//       }
//     }
//     if (pos == n) {
//       if (d_str[n] != fin[n - 4] * fin[n - 3] + fin[n - 3] * fin[n - 1] + fin[n - 1] * fin[n]) { fail = true;}
//       if (d_str[n - 1] != (fin[pos] - 1) * fin[pos - 2] + fin[pos - 2] * fin[pos - 3]) { fail = true; }
//     }
    if (fail) { continue; }
    if (Bt(pos + 1)) {
      return true;
    }
  }
  return false;
}
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;

  cin>>n;
#ifdef LOCAL
  RE (i, n) {
    cin>>cur[i];
    cerr<<cur[i]<<" ";
  }
  cerr<<endl;
#endif
  //int tr, str;
  tr = GetTr();
  str = GetStr();

  asks.PB(n);
  FOR (i, 2, n) {
    asks.PB(i);
  }
  if (n == 4) {
    asks = {4, 2, 3, 4};
  }
  pref[asks[0]][0] = 1;
  RE (i, n - 1) {
    RE (j, n) {
      pref[j][i] = pref[j][i - 1];
    }
    pref[asks[i]][i]++;
  }
  RE (i, n) {
    debug(i, pref[i][n - 1]);
  }

  RE (i, n) {
//     int ziom = i;
//     if (ziom == n) {
//       ziom = n - 2;
//     } /*else if (ziom == n - 1) {
//       ziom = n;
//     }*/
    cout<<"+ "<<asks[i - 1]<<endl;
    cur[asks[i - 1]]++;
    int ntr, nstr;
    ntr = GetTr();
    nstr = GetStr();
    d_tr[i] = ntr - tr;
    d_str[i] = nstr - str;
    if (d_tr[i] > 0) {
      debug(d_tr[i]);
      RE (j, n + 5) {
        if ((j - 1) * (j - 2) == 2 * d_tr[i]) {
          sure[asks[i - 1]] = j;
          //init[i] = j - 1;
          break;
        }
      }
      assert(sure[asks[i - 1]]);
    }
    tr = ntr;
    str = nstr;
  }
  RE (i, n) {
    debug(i, sure[i]);
  }
  Bt(1);
  cout<<"! ";
  RE (i, n) {
    cout<<init[i]<<" ";
  }
  cout<<endl;
#ifdef LOCAL
  RE (i, n) {
    assert(init[i] + pref[i][n - 1] == cur[i]);
  }
#endif

  return 0;
}


#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int N = 111;
int d_tr[N], d_str[N];
int sure[N];
int init[N];
int fin[N];
int n;
int val[N];
int cur[N];
int GetTr() {
#ifdef LOCAL
  int res = 0;
  RE (i, n) {
    res += (cur[i] * (cur[i] - 1) * (cur[i] - 2)) / 6;
  }
  return res;
#else
  int res;
  cin>>res;
  return res;
#endif
}
int GetStr() {
  int res = 0;
#ifdef LOCAL
  RE (i, n - 2) {
    res += cur[i] * (cur[i + 1] * cur[i + 2]);
  }
#else
  cin>>res;
#endif
  return res;
}
int tr, str;
int pref[N][N];
VI asks;
bool Bt(int pos) {

  if (pos == n + 1) {
    RE (i, n) {
      fin[i] = init[i];
    }
    REP (i, n) {
      fin[asks[i]]++;
    }
    int res = 0;
    RE (i, n) {
      res += (fin[i] * (fin[i] - 1) * (fin[i] - 2)) / 6;
    }
    if (res != tr) { return false; }
    res = 0;
    RE (i, n - 2) {
      res += fin[i] * fin[i + 1] * fin[i + 2];
    }
    if (res != str) { return false; }
    return true;
  }
  VI poss;
  if (pref[pos][n - 1] == 0) {
    REP (i, n + 1) {
      poss.PB(i);
    }
  } else if (sure[pos]) {
    poss.PB(sure[pos]);
    REP (i, n) {
      if (asks[i] == pos) {
        poss.back()--;
      }
    }
  } else {
    poss.PB(0);
    poss.PB(1);
  }
  //bool any = false;
  for (auto cand : poss) {
    init[pos] = cand;
    int fail = 0;
    REP (i, n) {
      int a = asks[i];
      if (a <= pos - 2 || pos == n) { // wszystko co potrzebne to juz mam ustalone
        int need = 0;
        if (a >= 3) {
          need += (init[a - 2] + pref[a - 2][i]) * (init[a - 1] + pref[a - 1][i]);
        }
        if (a >= 2) {
          need += (init[a - 1] + pref[a - 1][i]) * (init[a + 1] + pref[a + 1][i]);
        }
        need += (init[a + 1] + pref[a + 1][i]) * (init[a + 2] + pref[a + 2][i]);
        if (need != d_str[i + 1]) { fail = true; }
      }
    }
//     debug(pos);
//     RE (i, pos) {
//       cerr<<fin[i]<<" ";
//     }
//     cerr<<endl;
//     bool fail = false;
//     if (pos >= 3) {
//       int need = (fin[pos] - 1) * (fin[pos - 1] - 1) /** fin[pos - 2]*/;
//       if (pos >= 4) {
//         need += (fin[pos - 1] - 1) /** fin[pos - 2]*/ * fin[pos - 3];
//       }
//       if (pos >= 5) {
//         need += /*fin[pos - 2] **/ fin[pos - 3] * fin[pos - 4];
//       }
//       debug(pos, need, d_str[pos - 2]);
//       if (need != d_str[pos - 2]) {
//         fail = true;
//       }
//     }
//     if (pos == n) {
//       if (d_str[n] != fin[n - 4] * fin[n - 3] + fin[n - 3] * fin[n - 1] + fin[n - 1] * fin[n]) { fail = true;}
//       if (d_str[n - 1] != (fin[pos] - 1) * fin[pos - 2] + fin[pos - 2] * fin[pos - 3]) { fail = true; }
//     }
    if (fail) { continue; }
    if (Bt(pos + 1)) {
      return true;
    }
  }
  return false;
}
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;

  cin>>n;
#ifdef LOCAL
  RE (i, n) {
    cin>>cur[i];
    cerr<<cur[i]<<" ";
  }
  cerr<<endl;
#endif
  //int tr, str;
  tr = GetTr();
  str = GetStr();

  asks.PB(n);
  FOR (i, 2, n) {
    asks.PB(i);
  }
  if (n == 4) {
    asks = {4, 2, 3, 4};
  }
  pref[asks[0]][0] = 1;
  RE (i, n - 1) {
    RE (j, n) {
      pref[j][i] = pref[j][i - 1];
    }
    pref[asks[i]][i]++;
  }
  RE (i, n) {
    debug(i, pref[i][n - 1]);
  }

  RE (i, n) {
//     int ziom = i;
//     if (ziom == n) {
//       ziom = n - 2;
//     } /*else if (ziom == n - 1) {
//       ziom = n;
//     }*/
    cout<<"+ "<<asks[i - 1]<<endl;
    cur[asks[i - 1]]++;
    int ntr, nstr;
    ntr = GetTr();
    nstr = GetStr();
    d_tr[i] = ntr - tr;
    d_str[i] = nstr - str;
    if (d_tr[i] > 0) {
      debug(d_tr[i]);
      RE (j, n) {
        if ((j - 1) * (j - 2) == 2 * d_tr[i]) {
          sure[asks[i - 1]] = j;
          //init[i] = j - 1;
          break;
        }
      }
      assert(sure[asks[i - 1]]);
    }
    tr = ntr;
    str = nstr;
  }
  RE (i, n) {
    debug(i, sure[i]);
  }
  assert(Bt(1));
  cout<<"! ";
  RE (i, n) {
    cout<<init[i]<<" ";
  }
  cout<<endl;
#ifdef LOCAL
  RE (i, n) {
    assert(init[i] + pref[i][n - 1] == cur[i]);
  }
#endif

  return 0;
}


#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int N = 111;
int d_tr[N], d_str[N];
int sure[N];
int fin[N];
int n;
int val[N];
int cur[N];
int GetTr() {
#ifdef LOCAL
  int res = 0;
  RE (i, n) {
    res += (cur[i] * (cur[i] - 1) * (cur[i] - 2)) / 6;
  }
  return res;
#else
  int res;
  cin>>res;
  return res;
#endif
}
int GetStr() {
  int res = 0;
#ifdef LOCAL
  RE (i, n - 2) {
    res += cur[i] * (cur[i + 1] * cur[i + 2]);
  }
#else
  cin>>res;
#endif
  return res;
}

bool Bt(int pos) {

  if (pos == n + 1) {
    return true;
  }
  VI poss;
  if (sure[pos]) {
    poss.PB(sure[pos]);
  } else {
    poss.PB(1);
    poss.PB(2);
  }
  //bool any = false;
  for (auto cand : poss) {
    fin[pos] = cand;
    debug(pos);
    RE (i, pos) {
      cerr<<fin[i]<<" ";
    }
    cerr<<endl;
    bool fail = false;
    if (pos >= 3) {
      int need = (fin[pos] - 1) * (fin[pos - 1] - 1) /** fin[pos - 2]*/;
      if (pos >= 4) {
        need += (fin[pos - 1] - 1) /** fin[pos - 2]*/ * fin[pos - 3];
      }
      if (pos >= 5) {
        need += /*fin[pos - 2] **/ fin[pos - 3] * fin[pos - 4];
      }
      debug(need, d_str[pos - 2]);
      if (need != d_str[pos - 2]) {
        fail = true;
      }
    }
    if (pos == n) {
      if (d_str[n] != /*fin[pos] **/ fin[pos - 1] * fin[pos - 2]) { fail = true;}
      if (d_str[n - 1] != (fin[pos] - 1) /** fin[pos - 1]*/ * fin[pos - 2] + /*fin[pos - 1] **/ fin[pos - 2] * fin[pos - 3]) { fail = true; }
    }
    if (fail) { continue; }
    if (Bt(pos + 1)) {
      return true;
    }
  }
  return false;
}
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;

  cin>>n;
#ifdef LOCAL
  RE (i, n) {
    cin>>cur[i];
  }
#endif
  int tr, str;
  tr = GetTr();
  str = GetStr();
  RE (i, n) {
    cout<<"? "<<i<<endl;
    cur[i]++;
    int ntr, nstr;
    ntr = GetTr();
    nstr = GetStr();
    d_tr[i] = ntr - tr;
    d_str[i] = nstr - str;
    if (d_tr[i] > 0) {
      debug(d_tr[i]);
      RE (j, n) {
        if ((j - 1) * (j - 2) == 2 * d_tr[i]) {
          sure[i] = j;
          //init[i] = j - 1;
          break;
        }
      }
      assert(sure[i]);
    }
    tr = ntr;
    str = nstr;
  }
  RE (i, n) {
    debug(i, sure[i]);
  }
  assert(Bt(1));
  cout<<"! ";
  RE (i, n) {
    cout<<fin[i] - 1<<" ";
  }
  cout<<endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

// 💖 Hi, thanks for using ICIE! 💖
// 🔧 To use a custom code template, press Ctrl+Shift+P and select "ICIE Template configure" from the list 🔧
// 📝 If you spot any bugs or miss any features, create an issue at https://github.com/pustaczek/icie/issues 📝

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    scanf("%d", &n);
    int straight[n+1];
    int triplets[n+1];
    int deltastraight[n];
    int deltatriplets[n];
    scanf("%d %d", &triplets[n], &straight[n]);

    for(int i = n-1; i >= 0; i--){
        int index = i;
        if(i == 2)index = 1;
        else if(i == 1)index = 2;
        else if(i == 0)index = 1;

        printf("+ %d\n", index);
        fflush(stdout);
        scanf("%d %d", &triplets[i], &straight[i]);
        deltatriplets[i] = triplets[i]-triplets[i+1];
        deltastraight[i] = straight[i]-straight[i+1];
    }

    printf("here\n");
    int a[n+1];
    a[1] = (int)(sqrt(8*deltatriplets[0]+1)+1)/2;
    a[3] = deltastraight[0]-deltastraight[2]-1;
    a[2] = deltastraight[2]/(a[3]+1);
    a[4] = deltastraight[1]/(a[3]+1)-a[1]-2;
    for(int i = 5; i <= n; i++){
        a[i] = (deltastraight[i - 2] - a[i - 4] * a[i - 3]) / (a[i - 1] + 1) - a[i - 3] - 1;
    }
    printf("!");
    for(int i = 1; i <= n; i++)printf("%d ", a[i]);
}


#include <bits/stdc++.h>
using namespace std;

// 💖 Hi, thanks for using ICIE! 💖
// 🔧 To use a custom code template, press Ctrl+Shift+P and select "ICIE Template configure" from the list 🔧
// 📝 If you spot any bugs or miss any features, create an issue at https://github.com/pustaczek/icie/issues 📝

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    scanf("%d", &n);
    int straight[n+1];
    int triplets[n+1];
    int deltastraight[n];
    int deltatriplets[n];
    scanf("%d %d", &triplets[n], &straight[n]);

    for(int i = n-1; i >= 0; i--){
        int index = i;
        if(i <= 2){
            index = i % 2 + 1;
        }

        printf("+ %d\n", index);
        fflush(stdout);
        scanf("%d %d", &triplets[i], &straight[i]);
        deltatriplets[i] = triplets[i]-triplets[i+1];
        deltastraight[i] = straight[i]-straight[i+1];
    }

    int a[n+1];
    //a[1] = (int)(sqrt(8*deltatriplets[0]+1)+1)/2;
    a[1] = sqrt(deltatriplets[0]*2);
    a[3] = deltastraight[0]-deltastraight[2]-1;
    a[2] = deltastraight[2]/(a[3]+1);
    a[4] = deltastraight[1]/(a[3]+1)-a[1]-2;
    for(int i = 5; i <= n; i++){
        a[i] = (deltastraight[i - 2] - a[i - 4] * a[i - 3]) / (a[i - 1] + 1) - a[i - 3] - 1;
    }
    printf("!");
    for(int i = 1; i <= n; i++)printf(" %d", a[i]);
}


#include <bits/stdc++.h>
using namespace std;

// 💖 Hi, thanks for using ICIE! 💖
// 🔧 To use a custom code template, press Ctrl+Shift+P and select "ICIE Template configure" from the list 🔧
// 📝 If you spot any bugs or miss any features, create an issue at https://github.com/pustaczek/icie/issues 📝

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    scanf("%d", &n);
    int straight[n+1];
    int triplets[n+1];
    int deltastraight[n];
    int deltatriplets[n];
    scanf("%d %d", &triplets[n], &straight[n]);

    for(int i = n-1; i >= 0; i--){
        int index = i;
        if(i <= 2){
            index = i % 2 + 1;
        }

        printf("+ %d\n", index);
        fflush(stdout);
        scanf("%d %d", &triplets[i], &straight[i]);
        deltatriplets[i] = triplets[i]-triplets[i+1];
        deltastraight[i] = straight[i]-straight[i+1];
    }

    int a[n+1];
    //a[1] = (int)(sqrt(8*deltatriplets[0]+1)+1)/2;
    a[1] = sqrt(deltatriplets[0]*2);
    a[3] = deltastraight[0]-deltastraight[2]-1;
    a[2] = deltastraight[2]/(a[3]+1);
    a[4] = deltastraight[1]/(a[3]+1)-a[1]-2;
    for(int i = 5; i <= n; i++){
        a[i] = (deltastraight[i-2]-a[i-3]*(a[i-1]+1)-a[i-3]*a[i-4])/(a[i-1]+1)-1;
    }
    printf("!");
    for(int i = 1; i <= n; i++)printf(" %d", a[i]);
}


#include <bits/stdc++.h>
using namespace std;

// 💖 Hi, thanks for using ICIE! 💖
// 🔧 To use a custom code template, press Ctrl+Shift+P and select "ICIE Template configure" from the list 🔧
// 📝 If you spot any bugs or miss any features, create an issue at https://github.com/pustaczek/icie/issues 📝

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    scanf("%d", &n);
    int straight[n+1];
    int triplets[n+1];
    int deltastraight[n];
    int deltatriplets[n];
    scanf("%d %d", &triplets[n], &straight[n]);

    for(int i = n-1; i >= 0; i--){
        int index = i;
        if(i <= 2){
            index = i % 2 + 1;
        }

        printf("+ %d\n", index);
        fflush(stdout);
        scanf("%d %d", &triplets[i], &straight[i]);
        deltatriplets[i] = triplets[i]-triplets[i+1];
        deltastraight[i] = straight[i]-straight[i+1];
    }

    int a[n+1];
    //a[1] = (int)(sqrt(8*deltatriplets[0]+1)+1)/2;
    a[1] = sqrt(deltatriplets[0]*2);
    a[3] = deltastraight[0]-deltastraight[2]-1;
    a[2] = deltastraight[2]/(a[3]+1);
    a[4] = deltastraight[1]/(a[3]+1)-a[1]-2;
    for(int i = 5; i <= n; i++){
        a[i] = (deltastraight[i-2]-a[i-3]*(a[i-1]+1)-a[i-3]*a[i-4])/(a[i-1]+1)-1;
    }
    printf("!");a[n]++;
    for(int i = 1; i <= n; i++)printf(" %d", a[i]);
}


#include <bits/stdc++.h>
using namespace std;

// 💖 Hi, thanks for using ICIE! 💖
// 🔧 To use a custom code template, press Ctrl+Shift+P and select "ICIE Template configure" from the list 🔧
// 📝 If you spot any bugs or miss any features, create an issue at https://github.com/pustaczek/icie/issues 📝

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    scanf("%d", &n);
    int straight[n+1];
    int triplets[n+1];
    int deltastraight[n];
    int deltatriplets[n];
    scanf("%d %d", &triplets[n], &straight[n]);

    for(int i = n-1; i >= 0; i--){
        int index = i;
        if(i == 2)index = 1;
        else if(i == 1)index = 2;
        else if(i == 0)index = 1;

        printf("+ %d\n", index);
        fflush(stdout);
        scanf("%d %d", &triplets[i], &straight[i]);
        deltatriplets[i] = triplets[i]-triplets[i+1];
        deltastraight[i] = straight[i]-straight[i+1];
    }

    int a[n+1];
    a[1] = (int)(sqrt(8*deltatriplets[0]+1)+1)/2;
    a[3] = deltastraight[0]-deltastraight[2]-1;
    a[2] = deltastraight[2]/(a[3]+1);
    a[4] = deltastraight[1]/(a[3]+1)-a[1]-2;
    for(int i = 5; i <= n; i++){
        a[i] = (deltastraight[i-2]-a[i-3]*(a[i-1]+1)-a[i-3]*a[i-4])/(a[i-1]+1)-1;
    }
    printf("!");
    for(int i = 1; i <= n; i++)printf("%d ", a[i]);
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    bool q = (dstr[0] == b*c) && (dstr[1] == ((a+1)*c + c*d));
    return ((b == b_formula) && q && (last_str == (b + 1)*(c + 1)));
}

int soln = 0;
vector<int> sol[10];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    last_str = str1 - str;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[j]];
        if(test(a, j)){
            // Found good solution
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    bool q = (dstr[0] == b*c) && (dstr[1] == ((a+1)*c + c*d));
    return ((b == b_formula) && q && (last_str == (b + 1)*(c + 1)));
}

int soln = 0;
vector<int> sol[10];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    last_str = str - str1;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[j]];
        if(test(a, j)){
            // Found good solution
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];

    return (last_str == (b + 1)*(c + 1));
}

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    last_str = str1 - str;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[1]];
        if(test(a, j)){
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i <= n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        if(i < n)
            atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    bool q = (dstr[0] == b*c) && (dstr[1] == ((a+1)*c + c*d));
    return ((b == b_formula) && q);
}

int soln = 0;
vector<int> sol[10];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[j]];
        if(test(a, j)){
            // Found good solution
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }
    cin >> trip >> str;
    LL saved = 0;
    LL saved2 = 0;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();

        //cout << i - 1 << " " << freq[i - 1] << "\n";
        LL trip1, str1;
        cin >> trip1 >> str1;
        LL tripd = trip1 - trip;
        LL strd = str1 - str;

        if(tripd > 0){
            freq[i] = bin[tripd];
        }else{
            if(atleast1[i]){
                freq[i] = 1;
            }else{
                freq[i] = 0;
            }
        }
        if(i == 2){
            saved = strd;
        }
        if(i == 3){
            saved2 = strd;
        }

        LL prestr = 0;
        if(i > 2)
            prestr += 1LL*(freq[i-1] + 1)*(freq[i-2] + 1);
        if(strd > prestr){
            //cout << i + 1 << " at least 1 " << "\n";
            atleast1[i + 1] = 1;
        }
        trip = trip1;
        str = str1;
    }

    freq[1] = (saved2 - (freq[2]+1)*freq[4] - freq[4]*freq[3])/(freq[2] + 1) - 1;
    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();
}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    bool q = (dstr[0] == b*c) && (dstr[1] == ((a+1)*c + c*d));
    return ((b == b_formula) && q && (last_str == (b + 1)*(c + 1)));
}

int soln = 0;
vector<int> sol[10];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    last_str = str1 - str;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[1]];
        if(test(a, j)){
            // Found good solution
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];

void solve(){
    cin >> n;
    for(int i = 1; i <= 150; ++i){
        bin[i*(i - 1)/2] = i;
    }
    cin >> trip >> str;
    LL saved = 0;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();

        //cout << i - 1 << " " << freq[i - 1] << "\n";
        LL trip1, str1;
        cin >> trip1 >> str1;
        LL tripd = trip1 - trip;
        LL strd = str1 - str;

        if(tripd > 0){
            freq[i] = bin[tripd];
        }else{
            if(atleast1[i]){
                freq[i] = 1;
            }else{
                freq[i] = 0;
            }
        }
        if(i == 2){
            saved = strd;
        }

        LL prestr = 0;
        if(i > 2)
            prestr += 1LL*(freq[i-1] + 1)*(freq[i-2] + 1);
        if(strd > prestr){
            //cout << i + 1 << " at least 1 " << "\n";
            atleast1[i + 1] = 1;
        }
        trip = trip1;
        str = str1;
    }

    freq[1] = (saved - freq[3]*freq[4])/freq[3] - 1;
    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();
}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i <= n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int f = freq[6];
    int b_formula = (dstr[3] - e * f - (c + 1)*e)/(c + 1) - 1;
    int a_formula = (dstr[2] - d * e - (b_formula + 1)*d)/(b_formula + 1) - 1;

    return ((a == a_formula) && (b == b_formula));
}

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        int trip1, str1;
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }

    // At most 4 base cases to look for: [0, 0] and [1, 0] and [0, 1] and [1, 1].
    for(int i = 0; i <= 1; ++i){
        // If the triples change then the frequency
        // is bigger or equal to 2.
        if(dtrip[0] > 0)
            i = bin[dtrip[0]];

        for(int j = 0; j <= 1; ++j){
            if(dtrip[1] > 0)
                j = bin[dtrip[j]];
            if(test(i, j)){
                // Found good solution

                cout << "! ";
                for(int i = 1; i <= n; ++i){
                    cout << freq[i] << " ";
                }
                cout << "\n";
                cout.flush();

                return;
            }
        }
    }

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 10555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }
    cin >> trip >> str;
    LL saved = 0;
    LL saved2 = 0;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();

        //cout << i - 1 << " " << freq[i - 1] << "\n";
        LL trip1, str1;
        cin >> trip1 >> str1;
        LL tripd = trip1 - trip;
        LL strd = str1 - str;

        if(tripd > 0){
            freq[i] = bin[tripd];
        }else{
            if(atleast1[i]){
                freq[i] = 1;
            }else{
                freq[i] = 0;
            }
        }
        if(i == 2){
            saved = strd;
        }
        if(i == 3){
            saved2 = strd;
        }

        LL prestr = 0;
        if(i > 2)
            prestr += 1LL*(freq[i-1] + 1)*(freq[i-2] + 1);
        if(strd > prestr){
            //cout << i + 1 << " at least 1 " << "\n";
            atleast1[i + 1] = 1;
        }
        trip = trip1;
        str = str1;
    }

    freq[1] = (saved2 - (freq[2]+1)*freq[4] - freq[4]*freq[3])/(freq[2] + 1) - 1;
    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();
}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    return ((b == b_formula) && (last_str == (b + 1)*(c + 1)));
}

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    last_str = str1 - str;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[1]];
        if(test(a, j)){
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];

void solve(){
    cin >> n;
    for(int i = 1; i <= 150; ++i){
        bin[i*(i - 1)/2] = i;
    }
    cin >> trip >> str;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();

        //cout << i - 1 << " " << freq[i - 1] << "\n";
        LL trip1, str1;
        cin >> trip1 >> str1;
        LL tripd = trip1 - trip;
        LL strd = str1 - str;

        if(tripd > 0){
            freq[i] = bin[tripd];
        }else{

            if(atleast1[i]){
                freq[i] = 1;
            }else{
                freq[i] = 0;
            }
        }

        LL prestr = 0;
        if(i > 2)
            prestr += (freq[i-1] + 1)*(freq[i-2] + 1);
        if(strd > prestr){
            //cout << i + 1 << " at least 1 " << "\n";
            atleast1[i + 1] = 1;
        }
        trip = trip1;
        str = str1;
    }
    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();
}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }
    cin >> trip >> str;
    LL saved = 0;
    LL saved2 = 0;
    for(int i = 1; i <= n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();

        //cout << i - 1 << " " << freq[i - 1] << "\n";
        LL trip1, str1;
        cin >> trip1 >> str1;
        LL tripd = trip1 - trip;
        LL strd = str1 - str;

        if(tripd > 0){
            freq[i] = bin[tripd];
        }else{
            if(atleast1[i]){
                freq[i] = 1;
            }else{
                freq[i] = 0;
            }
        }
        if(i == 2){
            saved = strd;
        }
        if(i == 3){
            saved2 = strd;
        }

        LL prestr = 0;
        if(i > 2)
            prestr += 1LL*(freq[i-1] + 1)*(freq[i-2] + 1);
        if(strd > prestr){
            //cout << i + 1 << " at least 1 " << "\n";
            atleast1[i + 1] = 1;
        }
        trip = trip1;
        str = str1;
    }

    freq[1] = (saved2 - (freq[2]+1)*freq[4] - freq[4]*freq[5])/(freq[2] + 1) - 1;
    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();
}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <random>
#include <complex>
#include <chrono>
#include <assert.h>

using namespace std;

//ifstream fin("input.in");
//ofstream fout("output.out");

typedef long long LL;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const long long INF64 = 3e18 + 1;
const int NMAX = 3555;
const int AMAX = 205;

//typedef __uint128_t u128;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const char invdir[]{'L', 'U', 'R', 'D'};
const char dir[]{'R', 'D', 'L', 'U'};

int n;
LL trip, str;
int freq[NMAX];
int atleast1[NMAX];
int bin[NMAX*NMAX];
vector<int> dtrip, dstr;

bool test(int a, int b){
    memset(atleast1, 0, sizeof(atleast1));
    memset(freq, 0, sizeof(freq));

    // Test base cases of the induction
    freq[1] = a;
    freq[2] = b;

    if(dstr[1])
        atleast1[3] = 1;

    for(int i = 3; i < n; ++i){
        if(dtrip[i - 1] > 0){
            freq[i] = bin[dtrip[i - 1]];
        }else{
            freq[i] = atleast1[i];
        }
        atleast1[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    // Back-testing:

    int c = freq[3];
    int d = freq[4];
    int e = freq[5];
    int b_formula = (dstr[2] - d*e)/(a + d + 1) - 1;

    bool q = (dstr[0] == b*c) && (dstr[1] == ((a+1)*c + c*d));
    return ((b == b_formula) && q);
}

int soln = 0;
vector<int> sol[10];

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n";
        cout.flush();
        cin >> trip1 >> str1;
        int tripd = trip1 - trip;
        int strd = str1 - str;

        dtrip.push_back(tripd);
        dstr.push_back(strd);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n";
    cout.flush();
    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;

    for(int j = 0; j <= 1; ++j){
        if(dtrip[1] > 0)
            j = bin[dtrip[j]];
        if(test(a, j)){
            // Found good solution
            break;
        }
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n";
    cout.flush();

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    int T = 1;

    //cin >> T;

    int i = 1;
    while(T--){
        //cout << "Case #" << i << ": ";
        solve();
        //cout << "\n";
        i++;
    }

    return 0;
}


#include <iostream>
#include <cstring>
#include <vector>
#include <iomanip>

using namespace std;
const int NMAX = 505;

int n;
int trip, str;
int freq[NMAX], nonzero[NMAX], bin[NMAX*NMAX];
int last_str;
vector<int> dtrip, dstr;

bool test(int b){
    memset(nonzero, 0, sizeof(nonzero));
    // Test base cases of the induction
    freq[2] = b;

    if(dstr[1])
        nonzero[3] = 1;

    for(int i = 3; i < n; ++i){
        freq[i] = (dtrip[i - 1] > 0 ? bin[dtrip[i - 1]] : nonzero[i]);
        nonzero[i + 1] = (dstr[i - 1] > (1LL*(freq[i - 1] + 1)*(freq[i - 2] + 1)));
    }
    // Compute the last element:
    freq[n] = (dstr[(n - 1) - 1] - (freq[n - 2] + 1)*(freq[n - 3] + 1))/(freq[n - 2] + 1);

    return (last_str == (freq[2] + 1)*(freq[3] + 1));
}

void solve(){
    cin >> n;
    for(int i = 1; i <= 250; ++i){
        bin[i*(i - 1)/2] = i;
    }

    cin >> trip >> str;
    int trip1, str1;
    for(int i = 1; i < n; ++i){
        cout << "+ " << i << "\n" << flush;
        cin >> trip1 >> str1;

        dtrip.push_back(trip1 - trip);
        dstr.push_back(str1 - str);

        trip = trip1;
        str = str1;
    }
    // Saved the last query so we can fix the first element:
    int a = 0;
    cout << "+ " << 1 << "\n" << flush;

    cin >> trip1 >> str1;
    a = bin[(trip1 - trip)] - 1;
    freq[1] = a;

    last_str = str1 - str;

    // Two possibilities for b: 0 or 1 if dtrip[1] == 0 and just one if dtrip[1] > 0
    if(dtrip[1] == 0){
        for(int j = 0; j <= 1; ++j){
            if(test(j)){
                break;
            }
        }
    }else{
        test(bin[dtrip[1]]);
    }

    cout << "! ";
    for(int i = 1; i <= n; ++i){
        cout << freq[i] << " ";
    }
    cout << "\n" << flush;

}

int main() {
    std::cin.tie(0);
    std::ios_base::sync_with_stdio(0);
    std::cout << std::setprecision(16) << fixed;

    solve();

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define data asd09123jdf02i3h

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int n,a,b,s[maxn];

pii get(int x) {
    printf("+ %d\n",x);fflush(stdout);
    pii r;read(r.fr),read(r.sc);
    r.fr-=a,r.sc-=b,a=r.fr,b=r.sc;
    return r;
}

int main() {
    read(n),read(a),read(b);
    pii x=get(1),y=get(2),z=get(1);
    s[1]=(1+sqrt(1+8*z.fr))/2;
    s[3]=z.sc-x.sc;
    s[2]=x.sc/s[3];
    s[1]+=2,s[2]+=2;
    for(int i=2;i<=n-2;i++) {
        x=get(i);
        x.sc-=s[i-2]*s[i-1]+s[i-1]*s[i+1];
        x.sc/=s[i+1];
        s[i]=x.sc+1;
    }
    s[1]--,s[2]--;
    printf("! ");
    for(int i=1;i<=n;i++) printf("%d ",s[i]-1);puts("");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define data asd09123jdf02i3h

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int n,a,b,s[maxn];

pii get(int x) {
    printf("+ %d\n",x);fflush(stdout);
    pii r,t;read(r.fr),read(r.sc);t=r;
    r.fr-=a,r.sc-=b,a=t.fr,b=t.sc;
    return r;
}

pii r[maxn];

int main() {
    read(n),read(a),read(b);
    for(int i=n-1;i>=3;i--) r[i]=get(i);
    pii x=get(1),y=get(2),z=get(1);
    s[1]=(1+sqrt(1+8*z.fr))/2;
    s[3]=z.sc-x.sc;
    s[2]=x.sc/s[3]+1;
    s[4]=(y.sc-s[1]*s[3])/s[3];
    s[1]--,s[2]--;
    for(int i=3;i<=n-1;i++) {
        int v=r[i].sc-s[i-1]*s[i-2]-s[i-1]*s[i+1];
        s[i+2]=v/s[i+1];s[i]--;
    }
    printf("! ");
    for(int i=1;i<=n;i++) printf("%d ",s[i]);puts("");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

#define lf double
#define ll long long

#define pii pair<int,int >
#define vec vector<int >

#define pb push_back
#define mp make_pair
#define fr first
#define sc second

#define data asd09123jdf02i3h

#define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++)

const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;

int n,a,b,s[maxn];

pii get(int x) {
    printf("+ %d\n",x);fflush(stdout);
    pii r,t;read(r.fr),read(r.sc);t=r;
    r.fr-=a,r.sc-=b,a=t.fr,b=t.sc;
    return r;
}

pii r[maxn];

int main() {
    read(n),read(a),read(b);
    for(int i=n-1;i>=3;i--) r[i]=get(i);
    pii x=get(1),y=get(2),z=get(1);
    s[1]=(1+sqrt(1+8*z.fr))/2;
    s[3]=z.sc-x.sc;
    s[2]=x.sc/s[3]+1;
    s[4]=(y.sc-s[1]*s[3])/s[3];
    s[1]--,s[2]--;
    // cerr<<s[1]<<' '<<s[2]<<' '<<s[3]<<' '<<s[4]<<endl;
    for(int i=3;i<=n-1;i++) {
        int v=r[i].sc-s[i-1]*s[i-2]-s[i-1]*s[i+1];
        if(i<=n-2) s[i+2]=v/s[i+1];s[i]--;
    }
    printf("! ");
    for(int i=1;i<=n;i++) printf("%d ",s[i]);puts("");
    return 0;
}


// Problem : D. Yui and Mahjong Set
// Contest : Codeforces - Codeforces Round #635 (Div. 1)
// URL : https://codeforces.com/problemset/problem/1336/D
// Memory Limit : 256 MB
// Time Limit : 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

/*
 A Submission by $%U%$
 at time: $%Y%$-$%M%$-$%D%$ $%h%$:$%m%$:$%s%$
*/
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define rep(i,n) for(int64_t i=0;i < (int64_t)(n);i++)
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define FILE_IN "cseq.inp"
#define FILE_OUT "cseq.out"
#define ofile freopen(FILE_IN,"r",stdin);freopen(FILE_OUT,"w",stdout)
#define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define nfio cin.tie(0);cout.tie(0)
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))
#define ord(a,b,c) ((a>=b)and(b>=c))
#define MOD (ll(1000000007))
#define MAX 300001
#define mag 320
#define p1 first
#define p2 second.first
#define p3 second.second
#define fi first
#define se second
#define pow2(x) (ll(1)<<x)
#define pii pair<int,int>
#define piii pair<int,pii>
#define For(i,__,___) for(int i=__;i<=___;i++)
#define Rep(i,__,___) for(int i=__;i>=___;i--)
#define ordered_set tree<long long,null_type,less<long long>,rb_tree_tag,tree_order_statistics_node_update>
#define endl "\n"
#define bi BigInt
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
//---------END-------//
const int MN = 110;
ll res[MN];
ll ch[MN];
vi oof;
int sz;
void pre() {
	for(int i=0;i<MN;i++) {
		ch[i] = i*(i-1)*(i-2)/6;
	}
}
vi ba,bb;
ll wa[3],wb[3];
int main() {
	fio;
	int n;
	cin >> n;
	int pa,pb;
	cin >> pa >> pb;
	ba.push_back(pa);
	bb.push_back(pb);
	sz = n;
	pre();
	for(int i=n-1;i>=3;i--) {
		cout << "+ " << i << '\n';
		cout.flush();
		int a,b;
		cin >> a >> b;
		ba.push_back(a);
		bb.push_back(b);
	}
	int p[3] = {1,2,1};
	for(int i=0;i<3;i++) {
		cout << "+ " << p[i] << '\n';
		cout.flush();
		cin >> wa[i] >> wb[i];
	}
	for(int i=2;i<MN;i++) {
		if(wa[2]-wa[1] == ch[i]-ch[i-1]) {
			res[0] = i-2;
		}
	}
	res[2] = ((wb[2]-wb[1])-(wb[0]-bb.back()))-1;
	res[1] = ((wb[2]-wb[1]))/(res[2]+1)-1;
	res[3] = ((wb[1]-wb[0])/(res[2]+1))-res[0]-1-1;
	for(int i=4;i<n;i++) {
		int idx = bb.size()-(i-4)-1;
		int dif = bb[idx]-bb[idx-1];
		res[i] = (dif-res[i-4]*res[i-3] - res[i-3]*(res[i-1]+1))/(res[i-1]+1)-1;
	}
	res[n-1]++;
	cout << "!";
	for(int i=0;i<n;i++) {
		cout << " " << res[i];
	}
	cout << '\n';
	cout.flush();
}


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <assert.h>

typedef long long ll;

int n;
int ans[105];
int eqs[105];
int triplet, straight;
int ncrv[105] = {};

int findNcr(int diff) {
	for (int i = 0; i <= 100; i++) {
		if (ncrv[i + 1] - ncrv[i] == diff) {
			return i;
		}
	}
	assert(false);
}

long long nCr(int n, int r) {
    if (r > n / 2) r = n - r;
    long long ans = 1;
    for (int i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }
    return ans;
}

void guess() {
	printf("!");
	for (int i = 0; i < n; i++) {
		printf(" %d", ans[i]);
	}
	printf("\n");
	fflush(stdout);
}

void ask(int val) {
	printf("+ %d\n", val + 1);
	fflush(stdout);
	scanf("%d %d", &triplet, &straight);
}

void solveEven() {
	for (int i = 0; i < n; i += 2) {
		int pt = triplet;
		int ps = straight;
		bool found = false;
		ask(i);
		if (pt > triplet) {
			ans[i] = findNcr(triplet - pt);
			found = true;
		}
		pt = triplet;
		eqs[i / 2] = straight - ps;
		ask(i);
		if (!found) {
			if (pt > triplet) {
				ans[i] = 1;
			}
			else {
				ans[i] = 0;
			}
		}
	}
	ans[1] = eqs[0] / ans[2];
	for (int i = 1; i < n / 2 - 1; i++) {
		ans[i * 2 + 1] = (eqs[i] - ((ans[i * 2 - 2] + 2) * ans[i * 2 - 1])) / (ans[i * 2 - 1] + ans[i * 2 + 2]);
	}
	ans[n - 1] = eqs[n / 2 - 1] / ans[n - 3] - ans[n - 4] - 2;
}

void solveOdd() {
	for (int i = 1; i < n; i += 2) {
		int pt = triplet;
		int ps = straight;
		bool found = false;
		ask(i);
		if (pt > triplet) {
			ans[i] = findNcr(triplet - pt);
			found = true;
		}
		pt = triplet;
		eqs[i / 2] = straight - ps;
		ask(i);
		if (!found) {
			if (pt > triplet) {
				ans[i] = 1;
			}
			else {
				ans[i] = 0;
			}
		}
	}
	int ps = straight;
	ask(0);
	ans[2] = (straight - ps) / ans[1] - 2;
	ans[0] = eqs[0] / ans[2] - ans[3];
	for (int i = 1; i < n / 2 - 1; i++) {
		ans[i * 2 + 2] = (eqs[i] - ((ans[i * 2 - 1] + 2) * ans[i * 2])) / (ans[i * 2] + ans[i * 2 + 3]);
	}
	ans[n - 1] = eqs[n / 2 - 1] / ans[n - 3] - ans[n - 4] - 2;
}

int main() {
	scanf("%d", &n);
	scanf("%d %d", &triplet, &straight);
	for (int i = 3; i <= 100; i++) {
		ncrv[i] = nCr(i, 3);
	}
	if (n % 2 == 0) {
		solveEven();
	}
	else {
		solveOdd();
	}
	guess();

	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <assert.h>

typedef long long ll;

int n;
int ans[105];
int eqs[105];
int triplet, straight;
int ncrv[105] = {};

int findNcr(int diff) {
	for (int i = 0; i <= 100; i++) {
		if (ncrv[i + 1] - ncrv[i] == diff) {
			return i;
		}
	}
	assert(false);
}

long long nCr(int n, int r) {
    if (r > n / 2) r = n - r;
    long long ans = 1;
    for (int i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }
    return ans;
}

void guess() {
	printf("!");
	for (int i = 1; i <= n; i++) {
		printf(" %d", ans[i]);
	}
	printf("\n");
	fflush(stdout);
}

void ask(int val) {
	printf("+ %d\n", val);
	fflush(stdout);
	scanf("%d %d", &triplet, &straight);
}

void askAndPush(int val) {
	int pt = triplet;
	int ps = straight;
	ask(val);
	if (val <= 3 && triplet - pt > 0) {
		ans[val] = findNcr(triplet - pt);
	}
	eqs[val] = straight - ps;
}

void solve() {
	for (int i = n - 1; i >= 3; i--) {
		askAndPush(i);
	}
	askAndPush(1);
	askAndPush(2);

	int pt = triplet;
	int ps = straight;
	ask(1);
	if (ans[1] == 0) {
		if (triplet - pt > 0) {
			ans[1] = 1;
		}
		else {
			ans[1] = 0;
		}
	}
	int sdiff = straight - ps;
	if (ans[2] != 0) {
		ans[3] = sdiff / (ans[2] + 1) - 1;
	}
	else if (ans[3] != 0) {
		ans[2] = sdiff / (ans[3] + 1) - 1;
	}
	else if (ans[2] == 0 && ans[3] == 0) {
		if (eqs[1] == 0 && sdiff == 1) {
			ans[2] = 0;
			ans[3] = 0;
		}
		else if (eqs[1] == 0 && sdiff == 2) {
			ans[2] = 0;
			ans[3] = 1;
		}
		else if (eqs[1] == 1 && sdiff == 2) {
			ans[2] = 1;
			ans[3] = 0;
		}
		else if (eqs[1] == 2 && sdiff == 4) {
			ans[2] = 1;
			ans[3] = 1;
		}
		else {
			assert(false);
		}
	}
	ans[4] = (eqs[2] - (ans[1] + 1) * (ans[3] + 1)) / (ans[3] + 1) - 1;
	for (int i = 5; i <= n; i++) {
		ans[i] = (eqs[i - 2] - ans[i - 4] * ans[i - 3] - ans[i - 3] * (ans[i - 1] + 1)) / (ans[i - 1] + 1) - 1;
	}
	ans[n]++;
	guess();
}

int main() {
	scanf("%d", &n);
	scanf("%d %d", &triplet, &straight);
	for (int i = 3; i <= 100; i++) {
		ncrv[i] = nCr(i, 3);
	}
	solve();

	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <assert.h>

typedef long long ll;

int n;
int ans[105];
int eqs[105];
int triplet, straight;
int ncrv[109] = {};

int findNcr(int diff) {
	for (int i = 0; i <= 105; i++) {
		if (ncrv[i + 1] - ncrv[i] == diff) {
			return i;
		}
	}
	assert(false);
}

long long nCr(int n, int r) {
    if (r > n / 2) r = n - r;
    long long ans = 1;
    for (int i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }
    return ans;
}

void guess() {
	printf("!");
	for (int i = 1; i <= n; i++) {
		printf(" %d", ans[i]);
	}
	printf("\n");
	fflush(stdout);
}

void ask(int val) {
	printf("+ %d\n", val);
	fflush(stdout);
	scanf("%d %d", &triplet, &straight);
}

void askAndPush(int val) {
	int pt = triplet;
	int ps = straight;
	ask(val);
	if (val <= 3 && triplet - pt > 0) {
		ans[val] = findNcr(triplet - pt);
	}
	eqs[val] = straight - ps;
}

void solve() {
	for (int i = n - 1; i >= 3; i--) {
		askAndPush(i);
	}
	askAndPush(1);
	askAndPush(2);

	int pt = triplet;
	int ps = straight;
	ask(1);
	if (ans[1] == 0) {
		if (triplet - pt > 0) {
			ans[1] = 1;
		}
		else {
			ans[1] = 0;
		}
	}
	int sdiff = straight - ps;
	if (ans[2] != 0) {
		ans[3] = sdiff / (ans[2] + 1) - 1;
	}
	else if (ans[3] != 0) {
		ans[2] = sdiff / (ans[3] + 1) - 1;
	}
	else if (ans[2] == 0 && ans[3] == 0) {
		if (eqs[1] == 0 && sdiff == 1) {
			ans[2] = 0;
			ans[3] = 0;
		}
		else if (eqs[1] == 0 && sdiff == 2) {
			ans[2] = 0;
			ans[3] = 1;
		}
		else if (eqs[1] == 1 && sdiff == 2) {
			ans[2] = 1;
			ans[3] = 0;
		}
		else if (eqs[1] == 2 && sdiff == 4) {
			ans[2] = 1;
			ans[3] = 1;
		}
		else {
			assert(false);
		}
	}
	ans[4] = (eqs[2] - (ans[1] + 1) * (ans[3] + 1)) / (ans[3] + 1) - 1;
	for (int i = 5; i <= n; i++) {
		ans[i] = (eqs[i - 2] - ans[i - 4] * ans[i - 3] - ans[i - 3] * (ans[i - 1] + 1)) / (ans[i - 1] + 1) - 1;
	}
	ans[n]++;
	guess();
}

int main() {
	scanf("%d", &n);
	scanf("%d %d", &triplet, &straight);
	for (int i = 3; i <= 105; i++) {
		ncrv[i] = nCr(i, 3);
	}
	solve();

	return 0;
}