#include <bits/stdc++.h>
#pragma GCC optimize(2, 3, "Ofast")
using namespace std;
namespace fast_io {
char buf[1 << 12], *p1 = buf, *p2 = buf, sr[1 << 23], z[23], nc;
int C = -1, Z = 0, Bi = 0, ny;
inline char gc() {
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 12, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int read() {
  int x = 0;
  ny = 1;
  while (nc = gc(), (nc < 48 || nc > 57) && nc != EOF)
    if (nc == 45) ny = -1;
  Bi = 1;
  if (nc < 0) return nc;
  x = nc - 48;
  while (nc = gc(), 47 < nc && nc < 58 && nc != EOF)
    x = (x << 3) + (x << 1) + (nc ^ 48), Bi++;
  return x * ny;
}
inline double gf() {
  int a = read(), y = ny, b = (nc != '.') ? 0 : read();
  return (b ? a + (double)b / pow(10, Bi) * y : a);
}
inline int gs(char *s) {
  char c, *t = s;
  while (c = gc(), c < 32)
    ;
  *s++ = c;
  while (c = gc(), c > 32) *s++ = c;
  return s - t;
}
inline void ot() {
  fwrite(sr, 1, C + 1, stdout);
  C = -1;
}
inline void flush() {
  if (C > 1 << 22) ot();
}
template <typename T>
inline void write(T x, char t) {
  int y = 0;
  if (x < 0) y = 1, x = -x;
  while (z[++Z] = x % 10 + 48, x /= 10)
    ;
  if (y) z[++Z] = '-';
  while (sr[++C] = z[Z], --Z)
    ;
  sr[++C] = t;
  flush();
}
inline void write(char *s) {
  int l = strlen(s);
  for (int i = 0; i < l; i++) sr[++C] = *s++;
  sr[++C] = '\n';
  flush();
}
};  // namespace fast_io
using namespace fast_io;
const int N = 5e5 + 5;
int n, m, k, q;
struct E {
  int u, v, c;
} e[N];
struct P {
  int e, c;
} p[N];
vector<int> v[N];
vector<int>::iterator pos[N];
struct Dsu {
  int fa[500005];
  bool wi[500005];
  short h[500005];
  bool check(int id) {
    int u = e[id].u, v = e[id].v, w = 0;
    while (fa[u]) w ^= wi[u], u = fa[u];
    while (fa[v]) w ^= wi[v], v = fa[v];
    return u != v || w;
  }
  E merge(int u, int v) {
    int w = 1;
    while (fa[u]) w ^= wi[u], u = fa[u];
    while (fa[v]) w ^= wi[v], v = fa[v];
    if (u == v) return (E){0};
    h[u] > h[v] ? swap(u, v) : void(), fa[u] = v, wi[u] = w;
    return (E){u, v, (h[u] == h[v]) ? h[v]++ : h[v]};
  }
} dsu[51];
struct sgt {
  vector<E> t[N << 2], rec[205];
  inline void ins(int k, int d) {
    rec[d].clear();
    for (auto x : t[k]) rec[d].push_back(dsu[x.c].merge(x.u, x.v));
  }
  inline void del(int k, int d) {
    for (int i = t[k].size() - 1; ~i; i--)
      if (rec[d][i].u) {
        int u = rec[d][i].u, v = rec[d][i].v, c = t[k][i].c;
        dsu[c].fa[u] = dsu[c].wi[u] = 0, dsu[c].h[v] = rec[d][i].c;
      }
  }
  void add(int p, int l, int r, int L, int R, E v) {
    if (R < l || r < L) return;
    if (L <= l && r <= R) return t[p].push_back(v);
    add((p << 1), l, ((l + r) >> 1), L, R, v);
    add((p << 1 | 1), ((l + r) >> 1) + 1, r, L, R, v);
  }
  void work(int x, int l, int r, int d) {
    ins(x, d);
    if (l == r) {
      int id = p[l].e;
      pos[id]++;
      if (dsu[p[l].c].check(id))
        write("YES"), e[id].c = p[l].c;
      else
        write("NO");
      return add(1, 1, q, l + 1, (*pos[id]) - 1, e[id]), del(x, d);
    }
    work((x << 1), l, ((l + r) >> 1), d + 1),
        work((x << 1 | 1), ((l + r) >> 1) + 1, r, d + 1), del(x, d);
  }
} t;
int main() {
  n = read(), m = read(), k = read(), q = read();
  for (int i = 1; i <= m; i++) e[i] = {read(), read()};
  for (int i = 1; i <= q; i++) p[i] = {read(), read()}, v[p[i].e].push_back(i);
  for (int i = 1; i <= m; i++) v[i].push_back(q + 1), pos[i] = v[i].begin();
  t.work(1, 1, q, 0);
  return ot(), 0;
}
