#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1);
const double eps = 1e-6;
inline long long lgput(long long a, long long b, long long mod) {
  long long ret = 1;
  while (b) {
    if (b & 1) ret = (ret * a) % mod;
    a = (a * a) % mod;
    b >>= 1;
  }
  return (ret % mod);
}
inline long long inv(long long x, long long MOD) {
  return lgput(x, MOD - 2, MOD);
}
inline bool exist(double nr) { return (nr < -eps) || (nr > eps); }
long long big_rand() { return rand() * RAND_MAX + rand(); }
map<int, int> gr[100100];
map<int, int> vec[100100];
vector<int> ap[100100];
int dad[100100];
int superdad(int a) {
  if (dad[a] != a) {
    dad[a] = superdad(dad[a]);
  }
  return dad[a];
}
void bag(int a, int b) {
  for (auto &x : ap[dad[a]]) {
    vec[x][dad[b]] = 1;
    ap[dad[b]].push_back(x);
  }
  ap[dad[a]].clear();
  dad[dad[a]] = dad[b];
}
void unite(int a, int b) {
  superdad(a);
  superdad(b);
  if (dad[a] == dad[b]) {
    return;
  }
  if (ap[dad[a]].size() < ap[dad[b]].size()) {
    bag(a, b);
  } else {
    bag(b, a);
  }
}
void edge(int x, int y, int val) {
  if (gr[x][val]) {
    unite(y, gr[x][val]);
  }
  if (gr[y][val]) {
    unite(x, gr[y][val]);
  }
  gr[x][val] = y;
  gr[y][val] = x;
  superdad(x);
  superdad(y);
  vec[y][dad[x]] = 1;
  vec[x][dad[y]] = 1;
  ap[dad[x]].push_back(y);
  ap[dad[y]].push_back(x);
}
bool verif(int x, int y) {
  superdad(x);
  superdad(y);
  if (dad[x] == dad[y]) {
    return 1;
  }
  if (vec[y][dad[x]]) {
    return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cout << setprecision(10) << fixed;
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  srand(time(nullptr));
  int n, m, c, q;
  cin >> n >> m >> c >> q;
  for (int i = 1; i <= n; i++) {
    dad[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    int x, y, val;
    cin >> x >> y >> val;
    edge(x, y, val);
  }
  while (q--) {
    char ch;
    cin >> ch;
    if (ch == '+') {
      int x, y, val;
      cin >> x >> y >> val;
      edge(x, y, val);
    } else {
      int x, y;
      cin >> x >> y;
      if (verif(x, y)) {
        cout << "Yes" << '\n';
      } else {
        cout << "No" << '\n';
      }
    }
  }
  return 0;
}
