#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
map<int, vector<int> > M[N];
int sum[N];
set<int> S[N];
int root(int ary[], int i) {
  while (ary[i] != i) {
    ary[i] = ary[ary[i]];
    i = ary[i];
  }
  return i;
}
int un(int Ary[], int a, int b) {
  int rA = root(Ary, a);
  int rB = root(Ary, b);
  if (rA == rB) return 0;
  if (sum[rA] > sum[rB]) {
    for (auto it = S[rB].begin(); it != S[rB].end(); it++) {
      S[rA].insert(*it);
    }
    S[rB].clear();
    Ary[rB] = rA;
    sum[rA] += sum[rB];
  } else {
    for (auto it = S[rA].begin(); it != S[rA].end(); it++) {
      S[rB].insert(*it);
    }
    S[rA].clear();
    Ary[rA] = rB;
    sum[rB] += sum[rA];
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n, m, c, q;
  cin >> n >> m >> c >> q;
  int ary[n + 1];
  for (int i = 0; i < n + 1; ++i) sum[i] = 1;
  for (int i = 0; i < n + 1; ++i) {
    ary[i] = i;
    S[i].insert(i);
  }
  for (int i = 0; i < m; ++i) {
    int a, b, col;
    cin >> a >> b >> col;
    M[a][col].push_back(b);
    M[b][col].push_back(a);
    S[root(ary, a)].insert(b);
    S[root(ary, b)].insert(a);
    un(ary, M[a][col][0], b);
    un(ary, M[b][col][0], a);
  }
  while (q--) {
    char ch;
    cin >> ch;
    if (ch == '?') {
      int a, b;
      cin >> a >> b;
      if (S[root(ary, a)].find(b) != S[root(ary, a)].end())
        cout << "Yes"
             << "\n";
      else
        cout << "No"
             << "\n";
    } else {
      int a, b, col;
      cin >> a >> b >> col;
      M[a][col].push_back(b);
      M[b][col].push_back(a);
      S[root(ary, a)].insert(b);
      S[root(ary, b)].insert(a);
      un(ary, M[a][col][0], b);
      un(ary, M[b][col][0], a);
    }
  }
  return 0;
}
