#include <bits/stdc++.h>
using namespace std;
const int MAXBUF = 10000;
char buf[MAXBUF], *ps = buf, *pe = buf + 1;
inline bool isdigit(const char& n) { return (n >= '0' && n <= '9'); }
inline void rnext() {
  if (++ps == pe)
    pe = (ps = buf) +
         fread(buf, sizeof(char), sizeof(buf) / sizeof(char), stdin);
}
template <class T>
inline bool in(T& ans) {
  ans = 0;
  T f = 1;
  if (ps == pe) return false;
  do {
    rnext();
    if ('-' == *ps) f = -1;
  } while (!isdigit(*ps) && ps != pe);
  if (ps == pe) return false;
  do {
    ans = (ans << 1) + (ans << 3) + *ps - 48;
    rnext();
  } while (isdigit(*ps) && ps != pe);
  ans *= f;
  return true;
}
const int MAXOUT = 10000;
char bufout[MAXOUT], outtmp[50], *pout = bufout, *pend = bufout + MAXOUT;
inline void write() {
  fwrite(bufout, sizeof(char), pout - bufout, stdout);
  pout = bufout;
}
inline void out_char(char c) {
  *(pout++) = c;
  if (pout == pend) write();
}
inline void out_str(char* s) {
  while (*s) {
    *(pout++) = *(s++);
    if (pout == pend) write();
  }
}
template <class T>
inline void out_int(T x) {
  if (!x) {
    out_char('0');
    return;
  }
  if (x < 0) x = -x, out_char('-');
  int len = 0;
  while (x) {
    outtmp[len++] = x % 10 + 48;
    x /= 10;
  }
  outtmp[len] = 0;
  for (int i = 0, j = len - 1; i < j; i++, j--) swap(outtmp[i], outtmp[j]);
  out_str(outtmp);
}
template <typename T, typename... T2>
inline int in(T& value, T2&... value2) {
  in(value);
  return in(value2...);
}
const double eps = 1e-9;
const int maxn = 5e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N, M, tmp, K, Q;
struct Edge {
  int u, v, w, id;
} edge[maxn];
struct node {
  int w, id, pointer;
  friend bool operator<(node a, node b) { return a.w > b.w; }
};
vector<int> query[maxn];
priority_queue<node> P;
int Back[maxn][2];
int cnt;
int tree[maxn];
int Size[maxn];
int ans[maxn], ID[maxn];
void init() {
  for (register int i = 1; i <= N; i++) tree[i] = i, Size[i] = 1;
}
int find(int p) {
  if (p == tree[p]) return p;
  return find(tree[p]);
}
bool Union(int u, int v) {
  u = find(u);
  v = find(v);
  if (u == v) return false;
  if (Size[u] > Size[v]) swap(u, v);
  tree[u] = v;
  Size[v] += Size[u];
  Back[++cnt][0] = u;
  Back[cnt][1] = v;
  return true;
}
void Cancel() {
  while (cnt) {
    int u = Back[cnt][0];
    int v = Back[cnt--][1];
    tree[u] = u;
    Size[v] -= Size[u];
  }
}
bool cmp(Edge a, Edge b) { return a.w < b.w; }
int main() {
  in(N, M);
  init();
  for (register int i = 1; i <= M; i++)
    in(edge[i].u, edge[i].v, edge[i].w), edge[i].id = i;
  sort(edge + 1, edge + M + 1, cmp);
  for (register int i = 1; i <= M; i++) ID[edge[i].id] = i;
  in(Q);
  for (register int i = 1; i <= Q; i++) {
    in(tmp);
    while (tmp--) {
      int t;
      in(t);
      t = ID[t];
      query[i].push_back(t);
    }
    sort(query[i].begin(), query[i].end());
    node h;
    h.id = i;
    h.pointer = 0;
    h.w = query[i][0];
    P.push(h);
  }
  for (int i = 1; i <= M;) {
    int W = edge[i].w;
    int j = i + 1;
    for (; j <= M && edge[j].w == edge[i].w; j++)
      ;
    j--;
    while (!P.empty()) {
      node x = P.top();
      if (x.w > j) break;
      P.pop();
      int v = x.id;
      while (x.pointer < query[v].size() && query[v][x.pointer] <= j) {
        if (!Union(edge[query[v][x.pointer]].u, edge[query[v][x.pointer]].v))
          break;
        x.pointer++;
      }
      Cancel();
      if (x.pointer == query[v].size()) {
        ans[x.id] = 1;
        continue;
      }
      x.w = query[v][x.pointer];
      if (x.w > j) P.push(x);
    }
    for (; i <= j; i++) Union(edge[i].u, edge[i].v);
    cnt = 0;
  }
  for (register int i = 1; i <= Q; i++) {
    if (ans[i] == 1)
      puts("YES");
    else
      puts("NO");
  }
  return 0;
}
