#include <bits/stdc++.h>
using namespace std;
const int kn = 2e5 + 5, N = 1e5 + 5;
const long long mod = 1e9 + 7, mod2 = 1e9 + 9;
const long long base = 31, base1 = 37;
int n, m, color, q;
int par[N], size[N];
set<pair<int, int> > G[N];
set<int> adj[N];
int fin(int i) { return (par[i] == i) ? i : par[i] = fin(par[i]); }
void dj(int i, int j) {
  int pi = fin(i), pj = fin(j);
  if (pi == pj) return;
  if (size[pj] > size[pi]) swap(pi, pj);
  par[pj] = pi;
  size[pi] += size[pj];
  for (int t : adj[pj]) adj[pi].insert(t);
}
void add(int u, int v, int c) {
  int pu = fin(u), pv = fin(v);
  adj[pu].insert(v);
  adj[pv].insert(u);
  auto it = G[u].lower_bound({c, 0});
  if (it != G[u].end() && it->first == c) {
    dj(it->second, v);
  } else {
    G[u].insert(pair<int, int>(c, v));
  }
  it = G[v].lower_bound({c, 0});
  if (it != G[v].end() && it->first == c) {
    dj(it->second, u);
  } else {
    G[v].insert(pair<int, int>(c, u));
  }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &color, &q);
  for (int i = 1; i <= n; i++) {
    par[i] = i;
    size[i] = 1;
  }
  while (m--) {
    int u, v, c;
    scanf("%d%d%d", &u, &v, &c);
    add(u, v, c);
  }
  while (q--) {
    char type;
    int u, v;
    cin >> type;
    scanf("%d%d", &u, &v);
    if (type == '?') {
      int pu = fin(u), pv = fin(v);
      if (pu == pv)
        puts("Yes");
      else {
        if (adj[pu].find(v) != adj[pu].end())
          puts("Yes");
        else
          puts("No");
      }
    } else {
      int c;
      scanf("%d", &c);
      add(u, v, c);
    }
  }
}
