9 5 14
7 1 4 8 5 2 6 9 3
2 8
1 6
5 7
1 3
3 9
1 5
1 8
1 5
1 4
1 8
1 3
1 5
1 5
1 7
1 7
2 3
1 2
1 1
1 2
 6 5 8
1 2 6 3 4 5
2 4
1 3
1 6
3 5
2 5
1 1
1 4
1 1
2 1
2 5
2 2
2 3
1 4
 2 1 3
1 2
1 2
1 1
1 1
1 1

6
9
5
8
1
7
0
0
0
0
0
4
0
 6
5
4
3
 2
1
0

#include <bits/stdc++.h>
using VI = std::vector<int>;
struct ST {
  VI& src;
  VI arr;
  int p2;
  int imax(int i, int j) const {
    return (src[i] == src[j] ? i > j : src[i] > src[j]) ? i : j;
  }
  void update(int L, int R) {
    L = (L + p2) >> 1;
    R = (R + p2 + 1) >> 1;
    while (L) {
      for (int i = L; i < R; ++i) arr[i] = imax(arr[2 * i], arr[2 * i + 1]);
      L = L >> 1;
      R = (R + 1) >> 1;
    }
    return;
  }
  void update(int ix) {
    ix = (ix + p2) >> 1;
    while (ix) {
      arr[ix] = imax(arr[2 * ix], arr[2 * ix + 1]);
      ix >>= 1;
    }
    return;
  }
  ST(VI& _src) : src{_src} {
    int n = int(src.size());
    assert(n % 2 == 0);
    for (p2 = 1; p2 < n; p2 <<= 1)
      ;
    arr = VI(n + p2, n - 1);
    for (int i = 0; i < n; ++i) arr[i + p2] = i;
    update(0, n);
  }
  int rmq(int L, int R) const {
    int ans = L;
    L += p2;
    R += p2;
    while (L < R) {
      ans = imax(ans, arr[L]);
      ans = imax(ans, arr[R - 1]);
      L = (L + 1) >> 1;
      R >>= 1;
    }
    return ans;
  }
};
int main() {
  using namespace std;
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m, q;
  cin >> n >> m >> q;
  VI p = VI(n + 1);
  for (int i = 1; i <= n; ++i) cin >> p[i];
  struct UE {
    int priority;
    int u;
    int v;
  };
  vector<UE> edges = vector<UE>(m + 1);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    edges[i].priority = q + i;
    edges[i].u = p[u];
    edges[i].v = p[v];
  }
  struct Query {
    int priority;
    int v;
  };
  vector<Query> queries;
  queries.reserve(q);
  for (int i = 1; i <= q; ++i) {
    int t, v;
    cin >> t >> v;
    if (t == 1)
      queries.push_back(Query{i, v});
    else
      edges[v].priority = i;
  }
  struct E {
    int priority;
    int oSide;
    bool operator<(E o) const { return priority < o.priority; }
  };
  vector<vector<E>> gr = vector<vector<E>>(n + 1);
  for (UE e : edges) {
    gr[e.u].push_back(E{e.priority, e.v});
    gr[e.v].push_back(E{e.priority, e.u});
  }
  for (Query cq : queries) gr[p[cq.v]].push_back(E{cq.priority, -1});
  struct QueryInterval {
    int priority;
    int start;
    int stop;
  };
  vector<int> vertexLabels;
  vertexLabels.reserve(n + n % 2);
  vector<QueryInterval> qis;
  qis.reserve(queries.size());
  {
    priority_queue<E> pq;
    for (int i = 1; i <= n; ++i) pq.push(E{0, i});
    vector<char> vis = vector<char>(n + 1, char(false));
    struct PStackObj {
      int priority;
      int start;
    };
    vector<PStackObj> stack;
    while (!pq.empty()) {
      E e = pq.top();
      pq.pop();
      while (!stack.empty() && stack.back().priority >= e.priority)
        stack.pop_back();
      if (e.oSide == -1) {
        assert(!stack.empty());
        qis.push_back(QueryInterval{e.priority, stack.back().start,
                                    int(vertexLabels.size())});
      } else {
        if (vis[e.oSide]) continue;
        vis[e.oSide] = char(true);
        stack.push_back(PStackObj{e.priority, int(vertexLabels.size())});
        vertexLabels.push_back(e.oSide);
        for (E e2 : gr[e.oSide]) pq.push(e2);
      }
    }
    assert(int(vertexLabels.size()) == n);
    if (n % 2) vertexLabels.push_back(vertexLabels.back());
  }
  ST st{vertexLabels};
  sort(qis.begin(), qis.end(), [](QueryInterval qi1, QueryInterval qi2) {
    return qi1.priority < qi2.priority;
  });
  for (QueryInterval cqi : qis) {
    int i = st.rmq(cqi.start, cqi.stop);
    assert(0 <= i);
    assert(i < n);
    cout << vertexLabels[i] << endl;
    vertexLabels[i] = 0;
    st.update(i);
  }
  return 0;
}
