#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int pre[N], n, m;
int f(int x) { return pre[x] == x ? x : pre[x] = f(pre[x]); }
set<int> s[N];
map<int, vector<int> > v[N];
void join(int x, int y) {
  x = f(x);
  y = f(y);
  if (x == y) return;
  if (s[x].size() < s[y].size()) swap(x, y);
  set<int>::iterator it = s[y].begin();
  for (; it != s[y].end(); ++it) s[x].insert(*it);
  pre[y] = x;
}
void add() {
  int x, y, z;
  scanf("%d %d %d", &x, &y, &z);
  s[f(x)].insert(y);
  s[f(y)].insert(x);
  v[x][z].push_back(y);
  join(y, v[x][z][0]);
  v[y][z].push_back(x);
  join(x, v[y][z][0]);
}
void query() {
  int x, y;
  scanf("%d %d", &x, &y);
  if (f(x) == f(y) || s[f(x)].count(y))
    printf("Yes\n");
  else
    printf("No\n");
}
signed main() {
  char opt[10];
  int c, q;
  scanf("%d %d %d %d", &n, &m, &c, &q);
  for (register int i = (1); i <= (n); ++i) pre[i] = i;
  for (register int i = (1); i <= (m); ++i) add();
  for (register int i = (1); i <= (q); ++i) {
    scanf("%s", opt);
    if (opt[0] == '+')
      add();
    else
      query();
  }
  return 0;
}
