#include <bits/stdc++.h>
using namespace ::std;
const long double PI = acos(-1);
const long long MOD = 1000000000 + 7;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long add(long long a, long long b, long long m = MOD) {
  return (a % m + b % m + 2 * m) % m;
}
long long mul(long long a, long long b, long long m = MOD) {
  return ((a % m + m) * (b % m + m)) % m;
}
long long pow_mod(long long a, long long b, long long m = MOD) {
  long long res = 1LL;
  a = a % m;
  while (b) {
    if (b & 1) res = mul(res, a, m);
    b >>= 1;
    a = mul(a, a, m);
  }
  return res;
}
long long fastexp(long long a, long long b) {
  long long res = 1LL;
  while (b) {
    if (b & 1) res = res * a;
    b >>= 1;
    a *= a;
  }
  return res;
}
int gcdExtendido(int a, int b, int *x, int *y) {
  if (a == 0) {
    *x = 0;
    *y = 1;
    return b;
  }
  int x1, y1;
  int gcd = gcdExtendido(b % a, a, &x1, &y1);
  *x = y1 - (b / a) * x1;
  *y = x1;
  return gcd;
}
int modInverso(int a, int m) {
  int x, y;
  int g = gcdExtendido(a, m, &x, &y);
  if (g != 1)
    return -1;
  else
    return (x % m + m) % m;
}
const int N = 100000 + 5;
const int M = 400 + 5;
const int bucket = 400;
const int L = 18;
int a = 1;
class Trie {
  int nodos;
  vector<int> f[2];
  set<int> S;

 public:
  Trie(){};
  void setup(int x) {
    nodos = 1;
    int len = (100000 / x) + 5;
    int siz = (L + 1) * len;
    f[0].resize(siz);
    f[1].resize(siz);
    f[0].assign(siz, 0);
    f[1].assign(siz, 0);
  }
  void insert(int x) {
    int pos = 0;
    for (int i = L; i >= 0; i--) {
      int nxt = ((x >> i) & 1);
      if (f[nxt][pos] == 0) {
        f[nxt][pos] = nodos++;
      }
      pos = f[nxt][pos];
    }
    S.insert(x);
  }
  int query(int limit, int val) {
    if (a == 406) {
    }
    vector<pair<int, pair<int, int> > > reconstruir;
    int pos = 0;
    set<int>::iterator it = S.upper_bound(limit);
    if (*it > limit or it == S.end()) {
      if (it == S.begin()) return -1;
      it--;
    }
    int act = *it;
    for (int i = L; i >= 0; i--) {
      int want = ((act >> i) & 1);
      if (want == 0) {
        if (f[1][pos] != 0) {
          reconstruir.push_back(make_pair(f[1][pos], make_pair(1, pos)));
          f[1][pos] = 0;
        }
      }
      pos = f[want][pos];
    }
    pos = 0;
    int ans = 0;
    for (int i = L; i >= 0; i--) {
      int have = ((val >> i) & 1);
      int nxt = 1 ^ have;
      if (f[nxt][pos] == 0) {
        nxt ^= 1;
      }
      if (f[nxt][pos] == 0) {
        return -1;
      }
      ans += nxt << i;
      pos = f[nxt][pos];
    }
    for (auto x : reconstruir) {
      int val = x.first;
      int nxt = x.second.first;
      int pos = x.second.second;
      if (a == 406) {
      }
      f[nxt][pos] = val;
    }
    return ans <= limit ? ans : -1;
  }
};
int q;
bool vis[N];
Trie T[M];
void update(int x) {
  if (vis[x]) return;
  vis[x] = true;
  for (int i = 1; i <= bucket and i <= x; i++) {
    if (x % i == 0) {
      T[i].insert(x);
    }
  }
}
int solve(int x, int k, int s) {
  if (x % k != 0) {
    return -1;
  }
  if (s - x <= 0) {
    return -1;
  }
  if (k >= bucket) {
    int ans = -1;
    int XOR = -1;
    for (int v = k; v <= 1e5; v += k) {
      if (vis[v]) {
        if (v + x <= s) {
          if (XOR < int(v ^ x)) {
            ans = v;
            XOR = (v ^ x);
          }
        }
      }
    }
    return ans;
  } else {
    return T[k].query(s - x, x);
  }
}
int main() {
  scanf("%d", &(q));
  for (int i = 1; i <= bucket; i++) {
    T[i].setup(i);
  }
  int x, k, s;
  int op;
  while (q--) {
    scanf("%d", &(op));
    if (op == 1) {
      scanf("%d", &(x));
      update(x);
    } else {
      scanf("%d %d %d", &(x), &(k), &(s));
      printf("%d\n", solve(x, k, s));
    }
  }
  return 0;
}
