#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;
map<int, int> Q[N];
int dsu[N];
set<int> nearest[N];
int n, m, C, q;
int get(int v) {
  if (dsu[v] == v) {
    return v;
  }
  return dsu[v] = get(dsu[v]);
}
bool does(int a, int b) {
  if (get(a) == get(b)) {
    return 1;
  }
  return nearest[get(a)].count(b);
}
void merge(int a, int b) {
  a = get(a);
  b = get(b);
  if (a == b) {
    return;
  }
  if (nearest[a].size() < nearest[b].size()) {
    swap(a, b);
  }
  for (auto i : nearest[b]) {
    nearest[a].insert(i);
  }
  dsu[b] = a;
}
void addEdge(int a, int b, int c) {
  if (Q[a].count(c)) {
    merge(b, Q[a][c]);
  }
  if (Q[b].count(c)) {
    merge(a, Q[b][c]);
  }
  Q[a][c] = b;
  Q[b][c] = a;
  nearest[get(a)].insert(b);
  nearest[get(b)].insert(a);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> C >> q;
  for (int i = 0; i < n; ++i) {
    dsu[i] = i;
  }
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    addEdge(a, b, c);
  }
  for (int i = 0; i < q; ++i) {
    char c;
    cin >> c;
    if (c == '+') {
      int a, b, c;
      cin >> a >> b >> c;
      a--;
      b--;
      addEdge(a, b, c);
    } else {
      int a, b;
      cin >> a >> b;
      a--;
      b--;
      if (does(a, b)) {
        cout << "Yes\n";
      } else {
        cout << "No\n";
      }
    }
  }
  return 0;
}
