#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5;
vector<int> smallest_divisor;
void sieve() {
  smallest_divisor.resize(N);
  iota(smallest_divisor.begin(), smallest_divisor.end(), 0);
  for (int i = 2; i * i <= N; i++) {
    if (smallest_divisor[i] != i) continue;
    for (int j = i + i; j < N; j += i) {
      if (smallest_divisor[j] == j) smallest_divisor[j] = i;
    }
  }
  return;
}
vector<int> factorize(int n) {
  vector<int> pf;
  while (n > 1) {
    int d = smallest_divisor[n];
    pf.push_back(d);
    while (n % d == 0) n /= d;
  }
  return pf;
}
vector<vector<int>> tree;
vector<int> A, dist, val;
void dfs(int curr, int par, vector<int> &primes, int d = 0) {
  dist[curr] = d;
  vector<int> pf = factorize(val[curr]);
  int ans = -1;
  for (int i : pf) {
    if (primes[i] != -1) {
      if (ans == -1)
        ans = primes[i];
      else if (dist[ans] < dist[primes[i]])
        ans = primes[i];
    }
  }
  A[curr] = (ans == -1 ? -1 : ans + 1);
  vector<int> prev_values;
  for (int i : pf) {
    prev_values.push_back(primes[i]);
    primes[i] = curr;
  }
  for (int i : tree[curr]) {
    if (i != par) dfs(i, curr, primes, d + 1);
  }
  int idx = 0;
  for (int i : pf) {
    primes[i] = prev_values[idx];
    idx++;
  }
  return;
}
void update() {
  vector<int> primes(N, -1);
  dfs(0, -1, primes);
  return;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  sieve();
  int n, q;
  cin >> n >> q;
  val.resize(n), A.resize(n), tree.resize(n), dist.resize(n);
  for (int &i : val) cin >> i;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    tree[u].push_back(v);
    tree[v].push_back(u);
  }
  update();
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int node;
      cin >> node;
      node--;
      cout << A[node] << "\n";
    } else {
      int node, value;
      cin >> node >> value;
      node--;
      val[node] = value;
      update();
    }
  }
  return 0;
}
