#include <bits/stdc++.h>
using namespace std;
int Set(int N, int pos) { return N = N | (1 << pos); }
int reset(int N, int pos) { return N = N & ~(1 << pos); }
bool check(int N, int pos) { return (bool)(N & (1 << pos)); }
struct NODE {
  NODE* Child[2];
  int Min;
  NODE() {
    Child[0] = Child[1] = NULL;
    Min = INT_MAX;
  }
};
NODE* root[100005];
void INSERT(int x, int n) {
  NODE* Cur = root[x];
  for (int i = 18 - 1; i >= 0; i--) {
    int ID = check(n, i);
    if (Cur->Child[ID] == NULL) Cur->Child[ID] = new NODE();
    Cur = Cur->Child[ID];
    Cur->Min = min(Cur->Min, n);
  }
}
int QUERY(int k, int x, int L) {
  int Ans = 0;
  NODE* Cur = root[k];
  for (int i = 18 - 1; i >= 0; i--) {
    int ID = check(x, i);
    int Lim = check(L, i);
    bool now = ID ^ 1;
    if (Cur->Child[now] && Cur->Child[now]->Min <= L) {
      Cur = Cur->Child[now];
      Ans += (now << i);
      continue;
    }
    now = ID;
    if (Cur->Child[now] && Cur->Child[now]->Min <= L) {
      Cur = Cur->Child[now];
      Ans += (now << i);
      continue;
    }
    return -1;
  }
  return Ans;
}
vector<int> Div[100005];
int main() {
  for (int i = 1; i < 100005; i++)
    for (int j = i; j < 100005; j += i) Div[j].push_back(i);
  for (int i = 1; i < 100005; i++) root[i] = new NODE();
  int q, p;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int tp;
    scanf("%d", &tp);
    if (tp == 1) {
      scanf("%d", &p);
      for (auto v : Div[p]) INSERT(v, p);
    } else {
      int Id = -1;
      int x, k, s;
      scanf("%d %d %d", &x, &k, &s);
      if (x % k == 0 && s >= x) Id = QUERY(k, x, s - x);
      printf("%d\n", Id);
    }
  }
}
