#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, c, q;
int fa[N];
set<int> s[N];
map<int, int> G[N];
int fd(int x) { return fa[x] == x ? x : fa[x] = fd(fa[x]); }
void merge(int x, int y) {
  x = fd(x);
  y = fd(y);
  if (x == y) return;
  if (s[x].size() < s[y].size()) swap(x, y);
  fa[y] = x;
  s[x].insert(s[y].begin(), s[y].end());
  s[y].clear();
}
void add() {
  int u, v, w;
  scanf("%d%d%d", &u, &v, &w);
  if (G[u][w])
    merge(G[u][w], v);
  else
    G[u][w] = v;
  if (G[v][w])
    merge(G[v][w], u);
  else
    G[v][w] = u;
  s[fd(u)].insert(v);
  s[fd(v)].insert(u);
}
void query() {
  int x, y;
  scanf("%d%d", &x, &y);
  puts(((fd(x) == fd(y)) || (s[fd(x)].count(y))) ? "Yes" : "No");
}
int main() {
  scanf("%d%d%d%d", &n, &m, &c, &q);
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= m; i++) add();
  for (int i = 1; i <= q; i++) {
    char ch[10];
    scanf("%s", ch);
    if (ch[0] == '?')
      query();
    else
      add();
  }
  return 0;
}
