#include <bits/stdc++.h>
const int N = 100005;
std::map<int, int> rec[N];
std::set<int> adj[N];
int n, m, c, q, f[N];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void _union(int x, int y) {
  x = find(x), y = find(y);
  if (x == y) return;
  if (adj[x].size() > adj[y].size()) std::swap(x, y);
  f[x] = y;
  for (int p : adj[x]) adj[y].insert(p);
}
void link(int x, int y, int c) {
  if (rec[x].count(c))
    _union(rec[x][c], y);
  else
    rec[x][c] = y;
  if (rec[y].count(c))
    _union(rec[y][c], x);
  else
    rec[y][c] = x;
  adj[find(x)].insert(y);
  adj[find(y)].insert(x);
}
int main() {
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n >> m >> c >> q;
  for (int i = 1; i <= n; ++i) f[i] = i, adj[i].insert(i);
  for (int i = 0, x, y, c; i < m; ++i) std::cin >> x >> y >> c, link(x, y, c);
  while (q--) {
    char opt;
    int x, y, c;
    std::cin >> opt >> x >> y;
    if (opt == '?')
      std::cout << (adj[find(x)].count(y) ? "Yes" : "No") << '\n';
    else
      std::cin >> c, link(x, y, c);
  }
  return 0;
}
