#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 5e6 + 10;
const long long mod = 1e9 + 7;
map<int, int> ma[maxn];
set<int> se[maxn];
int n, m, c, q, boss[maxn];
void inti() {
  for (int i = 1; i <= n; i++) boss[i] = i;
}
int fin(int x) {
  if (boss[x] == x) return x;
  return boss[x] = fin(boss[x]);
}
void uni(int a, int b) {
  int v1 = fin(a), v2 = fin(b);
  if (v1 == v2) return;
  if (se[v1].size() > se[v2].size()) swap(v1, v2);
  boss[v1] = v2;
  for (auto i : se[v1]) se[v2].insert(i);
  se[v1].clear();
}
void add_edge() {
  int a, b, v;
  scanf("%d %d %d", &a, &b, &v);
  if (ma[a].count(v))
    uni(ma[a][v], b);
  else
    ma[a][v] = b;
  if (ma[b].count(v))
    uni(ma[b][v], a);
  else
    ma[b][v] = a;
  se[fin(a)].insert(b);
  se[fin(b)].insert(a);
}
int main() {
  scanf("%d %d %d %d", &n, &m, &c, &q);
  inti();
  for (int i = 1; i <= m; i++) add_edge();
  while (q--) {
    getchar();
    if (getchar() == '?') {
      int fla = 0, a, b;
      scanf("%d %d", &a, &b);
      int v = fin(a);
      if (v == fin(b) || se[v].find(b) != se[v].end())
        printf("Yes\n");
      else
        printf("No\n");
    } else {
      add_edge();
    }
  }
  return 0;
}
