package main
import (
"os"
)
func main() {
buf := make([]byte, 8192)
var pos, length int
readByte := func() byte {
if pos >= length {
n, err := os.Stdin.Read(buf)
if n == 0 || err != nil {
return 0
}
pos = 0
length = n
}
b := buf[pos]
pos++
return b
}
readInt := func() int {
b := readByte()
for b <= ' ' && b != 0 {
b = readByte()
}
if b == 0 {
return 0
}
res := 0
for b > ' ' {
res = res*10 + int(b-'0')
b = readByte()
}
return res
}
q := readInt()
if q == 0 {
return
}
type Op struct {
opType int
u int
x, k, s int
ans int
}
ops := make([]Op, q)
head := make([]int32, 100005)
tail := make([]int32, 100005)
for i := range head {
head[i] = -1
tail[i] = -1
}
type NodeList struct {
idx int32
next int32
}
list := make([]NodeList, 0, 2000000)
addToList := func(k int, idx int32) {
nodeIdx := int32(len(list))
list = append(list, NodeList{idx: idx, next: -1})
if head[k] == -1 {
head[k] = nodeIdx
tail[k] = nodeIdx
} else {
list[tail[k]].next = nodeIdx
tail[k] = nodeIdx
}
}
for i := 0; i < q; i++ {
t := readInt()
ops[i].opType = t
if t == 1 {
u := readInt()
ops[i].u = u
for d := 1; d*d <= u; d++ {
if u%d == 0 {
addToList(d, int32(i))
if d*d != u {
addToList(u/d, int32(i))
}
}
}
} else {
x := readInt()
k := readInt()
s := readInt()
ops[i].x = x
ops[i].k = k
ops[i].s = s
if x%k != 0 {
ops[i].ans = -1
} else {
addToList(k, int32(i))
}
}
}
type TrieNode struct {
child0 int32
child1 int32
min_val int32
}
trieNodes := make([]TrieNode, 2000000)
var sz int32
clearTrie := func() {
sz = 0
trieNodes[0].child0 = 0
trieNodes[0].child1 = 0
trieNodes[0].min_val = 1e9
}
newNode := func() int32 {
sz++
trieNodes[sz].child0 = 0
trieNodes[sz].child1 = 0
trieNodes[sz].min_val = 1e9
return sz
}
insertTrie := func(u int) {
curr := int32(0)
if trieNodes[curr].min_val > int32(u) {
trieNodes[curr].min_val = int32(u)
}
for i := 16; i >= 0; i-- {
bit := (u >> i) & 1
if bit == 0 {
if trieNodes[curr].child0 == 0 {
trieNodes[curr].child0 = newNode()
}
curr = trieNodes[curr].child0
} else {
if trieNodes[curr].child1 == 0 {
trieNodes[curr].child1 = newNode()
}
curr = trieNodes[curr].child1
}
if trieNodes[curr].min_val > int32(u) {
trieNodes[curr].min_val = int32(u)
}
}
}
queryTrie := func(x, s int) int {
if trieNodes[0].min_val > int32(s-x) {
return -1
}
curr := int32(0)
ans := 0
for i := 16; i >= 0; i-- {
bit := (x >> i) & 1
desired := 1 - bit
var best_child int32
var best_bit int
if desired == 0 {
if trieNodes[curr].child0 != 0 && trieNodes[trieNodes[curr].child0].min_val <= int32(s-x) {
best_child = trieNodes[curr].child0
best_bit = 0
} else {
best_child = trieNodes[curr].child1
best_bit = 1
}
} else {
if trieNodes[curr].child1 != 0 && trieNodes[trieNodes[curr].child1].min_val <= int32(s-x) {
best_child = trieNodes[curr].child1
best_bit = 1
} else {
best_child = trieNodes[curr].child0
best_bit = 0
}
}
ans |= (best_bit << i)
curr = best_child
}
return ans
}
var added = make([]int32, 100005)
var gen int32 = 0
for k := 1; k <= 100000; k++ {
if head[k] == -1 {
continue
}
hasQuery := false
curr := head[k]
for curr != -1 {
idx := list[curr].idx
if ops[idx].opType == 2 {
hasQuery = true
break
}
curr = list[curr].next
}
if !hasQuery {
continue
}
gen++
clearTrie()
curr = head[k]
for curr != -1 {
idx := list[curr].idx
op := &ops[idx]
if op.opType == 1 {
if added[op.u] != gen {
added[op.u] = gen
insertTrie(op.u)
}
} else {
op.ans = queryTrie(op.x, op.s)
}
curr = list[curr].next
}
}
outBuf := make([]byte, 0, 8192)
writeString := func(s string) {
outBuf = append(outBuf, s...)
if len(outBuf) >= 4096 {
os.Stdout.Write(outBuf)
outBuf = outBuf[:0]
}
}
writeInt := func(v int) {
if v == -1 {
writeString("-1\n")
return
}
if v == 0 {
writeString("0\n")
return
}
var buf [10]byte
idx := 10
for v > 0 {
idx--
buf[idx] = byte('0' + v%10)
v /= 10
}
outBuf = append(outBuf, buf[idx:]...)
outBuf = append(outBuf, '\n')
if len(outBuf) >= 4096 {
os.Stdout.Write(outBuf)
outBuf = outBuf[:0]
}
}
for i := 0; i < q; i++ {
if ops[i].opType == 2 {
writeInt(ops[i].ans)
}
}
if len(outBuf) > 0 {
os.Stdout.Write(outBuf)
}
}