#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
const int NMAX = 100000;
int n, m, timp;
int tin[NMAX + 5], tout[NMAX + 5], euler[NMAX + 5];
int p[NMAX + 5], it[NMAX + 5];
vector<int> g[NMAX + 5];
int mn[4 * NMAX + 5], mx[4 * NMAX + 5], lazy[4 * NMAX + 5], gd[4 * NMAX + 5];
void addnode(int nod, int x) {
mn[nod] += x;
mx[nod] += x;
lazy[nod] += x;
}
void push(int nod) {
if(!lazy[nod]) {
return;
}
addnode(nod * 2, lazy[nod]);
addnode(nod * 2 + 1, lazy[nod]);
lazy[nod] = 0;
}
void pull(int nod) {
mn[nod] = min(mn[nod * 2], mn[nod * 2 + 1]);
mx[nod] = max(mx[nod * 2], mx[nod * 2 + 1]);
gd[nod] = __gcd(gd[nod * 2], gd[nod * 2 + 1]);
gd[nod] = __gcd(gd[nod], abs(mn[nod * 2] - mn[nod * 2 + 1]));
}
void update(int nod, int l, int r, int a, int b, int x) {
if(a <= l && r <= b) {
addnode(nod, x);
return;
}
push(nod);
int mid = (l + r) / 2;
if(a <= mid) {
update(nod * 2, l, mid, a, b, x);
}
if(mid < b) {
update(nod * 2 + 1, mid + 1, r, a, b, x);
}
pull(nod);
}
int ok(int nod, int x) {
if(x < mn[nod] || x > mx[nod]) {
return 0;
}
if(gd[nod] && (x - mn[nod]) % gd[nod]) {
return 0;
}
return 1;
}
int query(int nod, int l, int r, int x) {
if(!ok(nod, x)) {
return -1;
}
if(mn[nod] == mx[nod]) {
return euler[l];
}
push(nod);
int mid = (l + r) / 2;
int ans = query(nod * 2, l, mid, x);
if(ans != -1) {
return ans;
}
return query(nod * 2 + 1, mid + 1, r, x);
}
int main() {
fin >> n >> m;
for(int i = 1; i < n; i++) {
int a, b;
fin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
stack<int> q;
q.push(1);
tin[1] = ++timp;
euler[timp] = 1;
while(!q.empty()) {
int nod = q.top();
if(it[nod] == (int)g[nod].size()) {
tout[nod] = timp;
q.pop();
continue;
}
int fiu = g[nod][it[nod]++];
if(fiu == p[nod]) {
continue;
}
p[fiu] = nod;
tin[fiu] = ++timp;
euler[timp] = fiu;
q.push(fiu);
}
while(m--) {
int tip;
fin >> tip;
if(tip == 1) {
int p, s;
fin >> p >> s;
update(1, 1, n, tin[p], tout[p], s);
} else {
int s;
fin >> s;
fout << query(1, 1, n, s) << "\n";
}
}
return 0;
}