You are given an undirected graph consisting of n vertices. Initially there are no edges in the graph. Also you are given q queries, each query either adds one undirected edge to the graph or removes it. After each query you have to check if the resulting graph is bipartite (that is, you can paint all vertices of the graph into two colors so that there is no edge connecting two vertices of the same color).

Input

The first line contains two integers n and q (2 ≤ n, q ≤ 100000).

Then q lines follow. ith line contains two numbers xi and yi (1 ≤ xi < yi ≤ n). These numbers describe ith query: if there is an edge between vertices xi and yi, then remove it, otherwise add it.

Output

Print q lines. ith line must contain YES if the graph is bipartite after ith query, and NO otherwise.

Example

Input

3 5
2 3
1 3
1 2
1 2
1 2


Output

YES
YES
NO
YES
NO
#include <bits/stdc++.h>
using namespace std;
struct Node {
  long long ra, szra, rb, parb, ptrb, bad_edges;
  Node(long long ra, long long szra, long long rb, long long parb,
       long long ptrb, long long bad_edges)
      : ra(ra),
        szra(szra),
        rb(rb),
        parb(parb),
        ptrb(ptrb),
        bad_edges(bad_edges) {}
  Node(long long bad_edges) : Node(0, 0, 0, 0, 0, bad_edges) {}
};
long long par[100003], sz[100003], parity[100003], bad_edges = 0;
pair<long long, long long> queries[100003];
map<pair<long long, long long>, vector<long long>> mp;
vector<pair<long long, long long>> seg[4 * 100003];
stack<Node> cache;
bool ans[100003];
void init(long long n) {
  for (long long i = 1; i <= n; i++) par[i] = i, sz[i] = 1, parity[i] = 0;
  bad_edges = 0;
}
long long root(long long p) {
  while (1) {
    if (p == par[p]) break;
    p = par[p];
  }
  return p;
}
long long getParity(long long p) {
  long long ans = 0;
  while (1) {
    ans = ans ^ parity[p];
    if (p == par[p]) break;
    p = par[p];
  }
  return ans;
}
bool merge(long long a, long long b) {
  long long ra = root(a);
  long long rb = root(b);
  long long pa = getParity(a);
  long long pb = getParity(b);
  if (ra == rb) {
    if (pa == pb) {
      cache.push(Node(bad_edges));
      bad_edges++;
      return false;
    } else {
      cache.push(Node(bad_edges));
      return true;
    }
  } else {
    if (sz[ra] < sz[rb]) swap(ra, rb), swap(pa, pb);
    cache.push(Node(ra, sz[ra], rb, par[rb], parity[rb], bad_edges));
    sz[ra] += sz[rb];
    par[rb] = ra;
    parity[rb] = pa ^ pb ^ 1;
    return true;
  }
}
void update(long long idx, long long l, long long r, long long sl, long long sr,
            pair<long long, long long> vl) {
  if (l > sr || r < sl) return;
  if (sl <= l && sr >= r) {
    seg[idx].push_back(vl);
    return;
  }
  long long md = (l + r) / 2;
  update(2 * idx, l, md, sl, sr, vl);
  update(2 * idx + 1, md + 1, r, sl, sr, vl);
}
void undo() {
  Node nd = cache.top();
  cache.pop();
  sz[nd.ra] = nd.szra;
  par[nd.rb] = nd.parb;
  parity[nd.rb] = nd.ptrb;
  bad_edges = nd.bad_edges;
}
void execute(long long idx, long long l, long long r) {
  for (auto e : seg[idx]) {
    merge(e.first, e.second);
  }
  if (l == r) {
    ans[l] = bad_edges == 0;
  } else {
    long long md = (l + r) / 2;
    execute(2 * idx, l, md);
    execute(2 * idx + 1, md + 1, r);
  }
  for (auto e : seg[idx]) {
    undo();
  }
}
int32_t main() {
  long long n, q, a, b;
  cin >> n >> q;
  init(n);
  for (long long i = 1; i <= q; i++) {
    cin >> queries[i].first >> queries[i].second;
    mp[queries[i]].push_back(i);
  }
  for (auto each : mp) {
    long long prev = -1;
    for (long long e : each.second) {
      if (prev == -1)
        prev = e;
      else {
        update(1, 1, q, prev, e - 1, each.first);
        prev = -1;
      }
    }
    if (prev != -1) {
      update(1, 1, q, prev, q, each.first);
    }
  }
  execute(1, 1, q);
  for (long long i = 1; i <= q; i++)
    if (ans[i])
      cout << "YES\n";
    else
      cout << "NO\n";
  return 0;
}
