#include <bits/stdc++.h>
using namespace std;
int dsupar[511111];
int rt(int u) {
  if (dsupar[u] < 0) return u;
  return (dsupar[u] = rt(dsupar[u]));
}
void merge(int u, int v) {
  u = rt(u);
  v = rt(v);
  if (u == v) return;
  if (dsupar[u] > dsupar[v]) swap(u, v);
  dsupar[u] += dsupar[v];
  dsupar[v] = u;
}
pair<long long, pair<long long, long long> > E[511111];
vector<pair<long long, long long> > T[511111];
vector<int> V[511111];
int n, m;
struct node {
  int to, next, cost;
} edge[2 * 501000];
int cnt, pre[501000];
void add_edge(int u, int v, int c) {
  edge[cnt].to = v;
  edge[cnt].next = pre[u];
  edge[cnt].cost = c;
  pre[u] = cnt++;
}
int deep[501000];
int order[501000];
int indx = 0;
int par[501000];
int parw[501000];
struct Lca_Online {
  int _n;
  int dp[501000][20];
  int dpw[501000][20];
  void _dfs(int s, int fa, int dd) {
    deep[s] = dd;
    order[s] = ++indx;
    for (int p = pre[s]; p != -1; p = edge[p].next) {
      int v = edge[p].to;
      if (v == fa) continue;
      _dfs(v, s, dd + 1);
      dp[v][0] = s;
      dpw[v][0] = edge[p].cost;
      par[v] = s;
    }
  }
  void _init() {
    for (int j = 1; (1 << j) <= _n; j++) {
      for (int i = 1; i <= _n; i++) {
        if (dp[i][j - 1] != -1) {
          dp[i][j] = dp[dp[i][j - 1]][j - 1];
          dpw[i][j] = max(dpw[i][j - 1], dpw[dp[i][j - 1]][j - 1]);
        } else
          dpw[i][j] = dpw[i][j - 1];
      }
    }
  }
  void lca_init(int n) {
    _n = n;
    memset(dp, -1, sizeof(dp));
    indx = 0;
    _dfs(0, -1, 0);
    _init();
  }
  int lca_query(int a, int b) {
    if (deep[a] > deep[b]) swap(a, b);
    for (int i = 20 - 1; deep[b] > deep[a]; i--)
      if (deep[b] - (1 << i) >= deep[a]) b = dp[b][i];
    if (a == b) return a;
    for (int i = 20 - 1; i >= 0; i--) {
      if (dp[a][i] != dp[b][i]) a = dp[a][i], b = dp[b][i];
    }
    return dp[a][0];
  }
  int get_max(int a, int b) {
    if (deep[a] > deep[b]) swap(a, b);
    int oria = a;
    int orib = b;
    int ans = 0;
    for (int i = 20 - 1; deep[b] > deep[a]; i--) {
      if (deep[b] - (1 << i) >= deep[a]) {
        ans = max(dpw[b][i], ans);
        b = dp[b][i];
      }
    }
    if (a == b) {
      return ans;
    }
    for (int i = 20 - 1; i >= 0; i--) {
      if (dp[a][i] != dp[b][i]) {
        ans = max(ans, max(dpw[i][a], dpw[i][b]));
        a = dp[a][i], b = dp[b][i];
      }
    }
    ans = max(ans, max(dpw[0][a], dpw[0][b]));
    return ans;
  }
} lca;
int stk[501000], top;
int mark[501000];
vector<int> tree[501000];
vector<int> treew[501000];
void tree_add(int u, int v, int w) {
  tree[u].push_back(v);
  tree[v].push_back(u);
  treew[u].push_back(w);
  treew[v].push_back(w);
}
int build_vtree(vector<int> &vp, int vn) {
  if (vn == 0) return -1;
  top = 0;
  stk[top++] = vp[0];
  tree[vp[0]].clear();
  treew[vp[0]].clear();
  mark[vp[0]] = 1;
  for (int i = 1; i < vn; i++) {
    int v = vp[i];
    int plca = lca.lca_query(stk[top - 1], v);
    if (plca == stk[top - 1])
      ;
    else {
      int pos = top - 1;
      while (pos >= 0 && deep[stk[pos]] > deep[plca]) pos--;
      pos++;
      for (int j = pos; j < top - 1; j++) {
        tree_add(stk[j], stk[j + 1], lca.get_max(stk[j], stk[j + 1]));
      }
      int prepos = stk[pos];
      if (pos == 0) {
        tree[plca].clear(), treew[plca].clear(), stk[0] = plca, top = 1;
        mark[plca] = 0;
      } else if (stk[pos - 1] != plca) {
        tree[plca].clear(), treew[plca].clear(), stk[pos] = plca, top = pos + 1;
        mark[plca] = 0;
      } else
        top = pos;
      tree_add(prepos, plca, lca.get_max(prepos, plca));
    }
    tree[v].clear();
    treew[v].clear();
    stk[top++] = v;
    mark[v] = 1;
  }
  for (int i = 0; i < top - 1; i++) {
    tree_add(stk[i], stk[i + 1], lca.get_max(stk[i], stk[i + 1]));
  }
  return vp[0];
}
struct vnode {
  int order, id;
} vg[501000];
int vcmp(vnode t1, vnode t2) { return t1.order < t2.order; }
int vsort(vector<int> &vp, int vn) {
  for (int i = 0; i < vn; i++) vg[i].id = vp[i], vg[i].order = order[vp[i]];
  sort(vg, vg + vn, vcmp);
  for (int i = 0; i < vn; i++) vp[i] = vg[i].id;
  return build_vtree(vp, vn);
}
long long res;
bool good[500101];
vector<pair<long long, pair<long long, long long> > > smalle;
void dfs(int u, int p) {
  for (int i = 0; i < tree[u].size(); i++) {
    int v = tree[u][i];
    if (v == p) continue;
    smalle.push_back(make_pair(treew[u][i], make_pair(u, v)));
    res += treew[u][i];
    dfs(v, u);
  }
}
int dsu2[500001];
int rt2(int u) {
  if (dsu2[u] < 0)
    return u;
  else
    return (dsu2[u] = rt2(dsu2[u]));
}
void merge2(int u, int v) {
  u = rt2(u);
  v = rt2(v);
  if (u == v) return;
  if (dsu2[u] > dsu2[v]) swap(u, v);
  dsu2[u] += dsu2[v];
  dsu2[v] = u;
}
long long solve(vector<int> &vec) {
  int rt = vsort(vec, vec.size());
  res = 0;
  if (rt != -1) {
    smalle.clear();
    dfs(rt, -1);
    sort(smalle.begin(), smalle.end());
    for (int i = 0; i + 1 < vec.size(); i++) {
      merge2(vec[i], vec[i + 1]);
    }
    for (int i = 0; i < smalle.size(); i++) {
      int u = smalle[i].second.first;
      int v = smalle[i].second.second;
      if (rt2(u) != rt2(v)) {
        res -= smalle[i].first;
        merge2(u, v);
      }
    }
    for (int i = 0; i < smalle.size(); i++) {
      dsu2[smalle[i].second.first] = dsu2[smalle[i].second.second] = -1;
    }
  }
  return res;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  memset(pre, -1, sizeof(pre));
  cin >> n >> m;
  memset(dsu2, -1, sizeof(dsu2));
  vector<pair<long long, pair<long long, long long> > > edges;
  memset(dsupar, -1, sizeof(dsupar));
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    E[i] = make_pair(w, make_pair(u, v));
    edges.push_back(E[i]);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; i++) {
    int u = edges[i].second.first;
    int v = edges[i].second.second;
    int w = edges[i].first;
    if (rt(u) != rt(v)) {
      T[u].push_back(make_pair(v, w));
      T[v].push_back(make_pair(u, w));
      add_edge(u, v, w);
      add_edge(v, u, w);
      merge(u, v);
    }
  }
  lca.lca_init(n);
  memset(dsupar, -1, sizeof(dsupar));
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int k;
    cin >> k;
    vector<int> involve;
    bool pos = 1;
    long long ans = 0;
    for (int j = 0; j < k; j++) {
      int x;
      cin >> x;
      x--;
      int u = E[x].second.first;
      int v = E[x].second.second;
      int w = E[x].first;
      ans += w;
      involve.push_back(u);
      involve.push_back(v);
      if (rt(u) == rt(v)) {
        pos = 0;
      } else {
        merge(u, v);
      }
    }
    if (!pos) {
      cout << "NO\n";
    } else {
      sort(involve.begin(), involve.end());
      involve.erase(unique(involve.begin(), involve.end()), involve.end());
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        good[u] = 1;
        V[rt(u)].push_back(u);
      }
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        if (u == rt(u)) {
          ans -= solve(V[u]);
        }
      }
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        good[u] = 0;
        if (u == rt(u)) V[u].clear();
      }
      if (ans == 0) {
        cout << "YES\n";
      } else {
        cout << "NO\n";
      }
    }
    for (int j = 0; j < involve.size(); j++) dsupar[involve[j]] = -1;
  }
}

### Prompt

Please formulate a Cpp solution to the following problem:

For a connected undirected weighted graph G, MST (minimum spanning tree) is a subgraph of G that contains all of G's vertices, is a tree, and sum of its edges is minimum possible.

You are given a graph G. If you run a MST algorithm on graph it would give you only one MST and it causes other edges to become jealous. You are given some queries, each query contains a set of edges of graph G, and you should determine whether there is a MST containing all these edges or not.

Input

The first line contains two integers n, m (2 ≤ n, m ≤ 5·105, n - 1 ≤ m) — the number of vertices and edges in the graph and the number of queries.

The i-th of the next m lines contains three integers ui, vi, wi (ui ≠ vi, 1 ≤ wi ≤ 5·105) — the endpoints and weight of the i-th edge. There can be more than one edges between two vertices. It's guaranteed that the given graph is connected.

The next line contains a single integer q (1 ≤ q ≤ 5·105) — the number of queries.

q lines follow, the i-th of them contains the i-th query. It starts with an integer ki (1 ≤ ki ≤ n - 1) — the size of edges subset and continues with ki distinct space-separated integers from 1 to m — the indices of the edges. It is guaranteed that the sum of ki for 1 ≤ i ≤ q does not exceed 5·105.

Output

For each query you should print "YES" (without quotes) if there's a MST containing these edges and "NO" (of course without quotes again) otherwise.

Example

Input

5 7
1 2 2
1 3 2
2 3 1
2 4 1
3 4 1
3 5 2
4 5 2
4
2 3 4
3 3 4 5
2 1 7
2 1 2


Output

YES
NO
YES
NO

Note

This is the graph of sample:

<image>

Weight of minimum spanning tree on this graph is 6.

MST with edges (1, 3, 4, 6), contains all of edges from the first query, so answer on the first query is "YES".

Edges from the second query form a cycle of length 3, so there is no spanning tree including these three edges. Thus, answer is "NO".

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
int dsupar[511111];
int rt(int u) {
  if (dsupar[u] < 0) return u;
  return (dsupar[u] = rt(dsupar[u]));
}
void merge(int u, int v) {
  u = rt(u);
  v = rt(v);
  if (u == v) return;
  if (dsupar[u] > dsupar[v]) swap(u, v);
  dsupar[u] += dsupar[v];
  dsupar[v] = u;
}
pair<long long, pair<long long, long long> > E[511111];
vector<pair<long long, long long> > T[511111];
vector<int> V[511111];
int n, m;
struct node {
  int to, next, cost;
} edge[2 * 501000];
int cnt, pre[501000];
void add_edge(int u, int v, int c) {
  edge[cnt].to = v;
  edge[cnt].next = pre[u];
  edge[cnt].cost = c;
  pre[u] = cnt++;
}
int deep[501000];
int order[501000];
int indx = 0;
int par[501000];
int parw[501000];
struct Lca_Online {
  int _n;
  int dp[501000][20];
  int dpw[501000][20];
  void _dfs(int s, int fa, int dd) {
    deep[s] = dd;
    order[s] = ++indx;
    for (int p = pre[s]; p != -1; p = edge[p].next) {
      int v = edge[p].to;
      if (v == fa) continue;
      _dfs(v, s, dd + 1);
      dp[v][0] = s;
      dpw[v][0] = edge[p].cost;
      par[v] = s;
    }
  }
  void _init() {
    for (int j = 1; (1 << j) <= _n; j++) {
      for (int i = 1; i <= _n; i++) {
        if (dp[i][j - 1] != -1) {
          dp[i][j] = dp[dp[i][j - 1]][j - 1];
          dpw[i][j] = max(dpw[i][j - 1], dpw[dp[i][j - 1]][j - 1]);
        } else
          dpw[i][j] = dpw[i][j - 1];
      }
    }
  }
  void lca_init(int n) {
    _n = n;
    memset(dp, -1, sizeof(dp));
    indx = 0;
    _dfs(0, -1, 0);
    _init();
  }
  int lca_query(int a, int b) {
    if (deep[a] > deep[b]) swap(a, b);
    for (int i = 20 - 1; deep[b] > deep[a]; i--)
      if (deep[b] - (1 << i) >= deep[a]) b = dp[b][i];
    if (a == b) return a;
    for (int i = 20 - 1; i >= 0; i--) {
      if (dp[a][i] != dp[b][i]) a = dp[a][i], b = dp[b][i];
    }
    return dp[a][0];
  }
  int get_max(int a, int b) {
    if (deep[a] > deep[b]) swap(a, b);
    int oria = a;
    int orib = b;
    int ans = 0;
    for (int i = 20 - 1; deep[b] > deep[a]; i--) {
      if (deep[b] - (1 << i) >= deep[a]) {
        ans = max(dpw[b][i], ans);
        b = dp[b][i];
      }
    }
    if (a == b) {
      return ans;
    }
    for (int i = 20 - 1; i >= 0; i--) {
      if (dp[a][i] != dp[b][i]) {
        ans = max(ans, max(dpw[i][a], dpw[i][b]));
        a = dp[a][i], b = dp[b][i];
      }
    }
    ans = max(ans, max(dpw[0][a], dpw[0][b]));
    return ans;
  }
} lca;
int stk[501000], top;
int mark[501000];
vector<int> tree[501000];
vector<int> treew[501000];
void tree_add(int u, int v, int w) {
  tree[u].push_back(v);
  tree[v].push_back(u);
  treew[u].push_back(w);
  treew[v].push_back(w);
}
int build_vtree(vector<int> &vp, int vn) {
  if (vn == 0) return -1;
  top = 0;
  stk[top++] = vp[0];
  tree[vp[0]].clear();
  treew[vp[0]].clear();
  mark[vp[0]] = 1;
  for (int i = 1; i < vn; i++) {
    int v = vp[i];
    int plca = lca.lca_query(stk[top - 1], v);
    if (plca == stk[top - 1])
      ;
    else {
      int pos = top - 1;
      while (pos >= 0 && deep[stk[pos]] > deep[plca]) pos--;
      pos++;
      for (int j = pos; j < top - 1; j++) {
        tree_add(stk[j], stk[j + 1], lca.get_max(stk[j], stk[j + 1]));
      }
      int prepos = stk[pos];
      if (pos == 0) {
        tree[plca].clear(), treew[plca].clear(), stk[0] = plca, top = 1;
        mark[plca] = 0;
      } else if (stk[pos - 1] != plca) {
        tree[plca].clear(), treew[plca].clear(), stk[pos] = plca, top = pos + 1;
        mark[plca] = 0;
      } else
        top = pos;
      tree_add(prepos, plca, lca.get_max(prepos, plca));
    }
    tree[v].clear();
    treew[v].clear();
    stk[top++] = v;
    mark[v] = 1;
  }
  for (int i = 0; i < top - 1; i++) {
    tree_add(stk[i], stk[i + 1], lca.get_max(stk[i], stk[i + 1]));
  }
  return vp[0];
}
struct vnode {
  int order, id;
} vg[501000];
int vcmp(vnode t1, vnode t2) { return t1.order < t2.order; }
int vsort(vector<int> &vp, int vn) {
  for (int i = 0; i < vn; i++) vg[i].id = vp[i], vg[i].order = order[vp[i]];
  sort(vg, vg + vn, vcmp);
  for (int i = 0; i < vn; i++) vp[i] = vg[i].id;
  return build_vtree(vp, vn);
}
long long res;
bool good[500101];
vector<pair<long long, pair<long long, long long> > > smalle;
void dfs(int u, int p) {
  for (int i = 0; i < tree[u].size(); i++) {
    int v = tree[u][i];
    if (v == p) continue;
    smalle.push_back(make_pair(treew[u][i], make_pair(u, v)));
    res += treew[u][i];
    dfs(v, u);
  }
}
int dsu2[500001];
int rt2(int u) {
  if (dsu2[u] < 0)
    return u;
  else
    return (dsu2[u] = rt2(dsu2[u]));
}
void merge2(int u, int v) {
  u = rt2(u);
  v = rt2(v);
  if (u == v) return;
  if (dsu2[u] > dsu2[v]) swap(u, v);
  dsu2[u] += dsu2[v];
  dsu2[v] = u;
}
long long solve(vector<int> &vec) {
  int rt = vsort(vec, vec.size());
  res = 0;
  if (rt != -1) {
    smalle.clear();
    dfs(rt, -1);
    sort(smalle.begin(), smalle.end());
    for (int i = 0; i + 1 < vec.size(); i++) {
      merge2(vec[i], vec[i + 1]);
    }
    for (int i = 0; i < smalle.size(); i++) {
      int u = smalle[i].second.first;
      int v = smalle[i].second.second;
      if (rt2(u) != rt2(v)) {
        res -= smalle[i].first;
        merge2(u, v);
      }
    }
    for (int i = 0; i < smalle.size(); i++) {
      dsu2[smalle[i].second.first] = dsu2[smalle[i].second.second] = -1;
    }
  }
  return res;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  memset(pre, -1, sizeof(pre));
  cin >> n >> m;
  memset(dsu2, -1, sizeof(dsu2));
  vector<pair<long long, pair<long long, long long> > > edges;
  memset(dsupar, -1, sizeof(dsupar));
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    E[i] = make_pair(w, make_pair(u, v));
    edges.push_back(E[i]);
  }
  sort(edges.begin(), edges.end());
  for (int i = 0; i < m; i++) {
    int u = edges[i].second.first;
    int v = edges[i].second.second;
    int w = edges[i].first;
    if (rt(u) != rt(v)) {
      T[u].push_back(make_pair(v, w));
      T[v].push_back(make_pair(u, w));
      add_edge(u, v, w);
      add_edge(v, u, w);
      merge(u, v);
    }
  }
  lca.lca_init(n);
  memset(dsupar, -1, sizeof(dsupar));
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int k;
    cin >> k;
    vector<int> involve;
    bool pos = 1;
    long long ans = 0;
    for (int j = 0; j < k; j++) {
      int x;
      cin >> x;
      x--;
      int u = E[x].second.first;
      int v = E[x].second.second;
      int w = E[x].first;
      ans += w;
      involve.push_back(u);
      involve.push_back(v);
      if (rt(u) == rt(v)) {
        pos = 0;
      } else {
        merge(u, v);
      }
    }
    if (!pos) {
      cout << "NO\n";
    } else {
      sort(involve.begin(), involve.end());
      involve.erase(unique(involve.begin(), involve.end()), involve.end());
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        good[u] = 1;
        V[rt(u)].push_back(u);
      }
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        if (u == rt(u)) {
          ans -= solve(V[u]);
        }
      }
      for (int j = 0; j < involve.size(); j++) {
        int u = involve[j];
        good[u] = 0;
        if (u == rt(u)) V[u].clear();
      }
      if (ans == 0) {
        cout << "YES\n";
      } else {
        cout << "NO\n";
      }
    }
    for (int j = 0; j < involve.size(); j++) dsupar[involve[j]] = -1;
  }
}

```