#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using si = set<int>;
using sii = set<pii>;
sii G[100005];
si g[100005];
int p[100005];
int f(int x) { return (x == p[x]) ? x : p[x] = f(p[x]); }
void un(int x, int y) {
  x = f(x), y = f(y);
  if (x == y) return;
  if (g[y].size() < g[x].size()) swap(x, y);
  p[x] = y;
  for (auto u : g[x]) g[y].insert(u);
  g[x].clear();
}
int n;
int main() {
  int m, c, q;
  scanf("%d%d%d%d", &n, &m, &c, &q);
  for (int i = 1; i <= n; i++) p[i] = i;
  for (int i = 1; i <= m; i++) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    auto l1 = G[x].lower_bound({z, 0});
    auto l2 = G[y].lower_bound({z, 0});
    G[x].emplace(z, y);
    G[y].emplace(z, x);
    int px = f(x), py = f(y);
    if (px != py) {
      g[px].insert(y);
      g[py].insert(x);
    }
    if (l1 != G[x].end() and l1->first == z) un(l1->second, y);
    if (l2 != G[y].end() and l2->first == z) un(l2->second, x);
  }
  for (int i = 1; i <= q; i++) {
    char c;
    scanf(" %c", &c);
    if (c == '+') {
      int x, y, z;
      scanf("%d%d%d", &x, &y, &z);
      auto l1 = G[x].lower_bound({z, 0});
      auto l2 = G[y].lower_bound({z, 0});
      G[x].emplace(z, y);
      G[y].emplace(z, x);
      int px = f(x), py = f(y);
      if (px != py) {
        g[px].insert(y);
        g[py].insert(x);
      }
      if (l1 != G[x].end() and l1->first == z) un(l1->second, y);
      if (l2 != G[y].end() and l2->first == z) un(l2->second, x);
    } else if (c == '?') {
      int x, y;
      scanf("%d%d", &x, &y);
      int px = f(x), py = f(y);
      if (px == py)
        printf("Yes\n");
      else if (g[px].find(y) != g[px].end())
        printf("Yes\n");
      else
        printf("No\n");
    }
  }
}
