#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, m, C, q, fa[N];
char ch;
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
map<int, int> mp[N], can[N];
map<int, int>::iterator it;
void merge(int x, int y) {
  if (x != y) {
    if (can[x].size() > can[y].size()) swap(x, y);
    fa[x] = y;
    for (it = can[x].begin(); it != can[x].end(); it++)
      can[y][it->first] = can[y][it->first] | it->second;
  }
}
void add(int x, int y, int c) {
  if (mp[y][c]) merge(find(x), find(mp[y][c]));
  if (mp[x][c]) merge(find(y), find(mp[x][c]));
  mp[x][c] = y, mp[y][c] = x;
  can[find(x)][y] = can[find(y)][x] = 1;
}
int main() {
  cin >> n >> m >> C >> q;
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= n; i++) can[i][i] = 1;
  for (int i = 1, x, y, c; i <= m; i++) {
    cin >> x >> y >> c;
    add(x, y, c);
  }
  for (int i = 1, x, y, c; i <= q; i++) {
    cin >> ch;
    if (ch == '?') {
      cin >> x >> y;
      if (!can[find(x)].count(y))
        cout << "No\n";
      else
        cout << "Yes\n";
    } else {
      cin >> x >> y >> c;
      add(x, y, c);
    }
  }
}
