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
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskF solver = new TaskF();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskF {
		int n;
		int[] queryA;
		int[] queryB;
		boolean[] ans;
		int[] match;
		DSUWithRollbacks dsu;

		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			n = in.nextInt();
			int numQueries = in.nextInt();
			queryA = new int[numQueries];
			queryB = new int[numQueries];
			for (int i = 0; i < numQueries; i++) {
				int a = in.nextInt() - 1;
				int b = in.nextInt() - 1;
				queryA[i] = Math.min(a, b);
				queryB[i] = Math.max(a, b);
			}
			ans = new boolean[numQueries];
			match = new int[numQueries];
			Map<Long, Integer> where = new HashMap<>();
			for (int i = 0; i < numQueries; i++) {
				long key = queryA[i] * (long) n + queryB[i];
				if (where.containsKey(key)) {
					int j = where.get(key);
					where.remove(key);
					match[i] = j;
					match[j] = i;
				} else {
					match[i] = -1;
					where.put(key, i);
				}
			}
			dsu = new DSUWithRollbacks(n);
			solve(0, numQueries - 1);
			for (int i = 0; i < numQueries; i++) {
				out.println(ans[i] ? "YES" : "NO");
			}
		}

		private void solve(int l, int r) {
			int k = 0;
			if (l == r) {
				if (match[l] < 0 || match[l] > l) {
					dsu.merge(queryA[l], queryB[l]);
					++k;
				}
				ans[l] = dsu.numViolations == 0;
				while (k > 0) {
					dsu.rollback();
					--k;
				}
				return;
			}

			int m = (l + r) / 2;

			for (int i = m + 1; i <= r; i++) {
				int j = match[i];
				if (j >= 0 && j < l) {
					dsu.merge(queryA[j], queryB[j]);
					++k;
				}
			}
			solve(l, m);
			while (k > 0) {
				dsu.rollback();
				--k;
			}

			for (int i = l; i <= m; i++) {
				int j = match[i];
				if (j < 0 || j > r) {
					dsu.merge(queryA[i], queryB[i]);
					++k;
				}
			}
			solve(m + 1, r);
			while (k > 0) {
				dsu.rollback();
				--k;
			}
		}

		class DSUWithRollbacks {
			int[] p;
			int[] size;
			boolean[] sameColAsParent;
			List<Integer> changes = new ArrayList<>();
			int numViolations = 0;

			DSUWithRollbacks(int n) {
				p = new int[n];
				size = new int[n];
				sameColAsParent = new boolean[n];
				for (int i = 0; i < n; i++) {
					p[i] = i;
					size[i] = 1;
				}
			}

			int getComp(int x) {
				while (x != p[x]) {
					x = p[x];
				}
				return x;
			}

			boolean col(int x) {
				if (x == p[x]) {
					return false;
				}
				return col(p[x]) ^ sameColAsParent[x];
			}

			void merge(int a, int b) {
				int ca = getComp(a);
				int cb = getComp(b);
				if (size[ca] > size[cb]) {
					int t = ca;
					ca = cb;
					cb = t;
					t = a;
					a = b;
					b = t;
				}

				boolean same = col(a) == col(b);
				changes.add(ca);
				changes.add(cb);
				changes.add(p[ca]);
				changes.add(size[cb]);
				changes.add(same ? 1 : 0);
				if (ca == cb) {
					if (same) {
						++numViolations;
					}
					return;
				}
				p[ca] = cb;
				sameColAsParent[ca] = same;
				size[cb] += size[ca];
			}

			void rollback() {
				int ca = changes.get(changes.size() - 5);
				int cb = changes.get(changes.size() - 4);
				int pa = changes.get(changes.size() - 3);
				int sb = changes.get(changes.size() - 2);
				boolean same = changes.get(changes.size() - 1) == 1;
				for (int i = 0; i < 5; i++) {
					changes.remove(changes.size() - 1);
				}

				if (ca == cb) {
					if (same) {
						--numViolations;
					}
					return;
				}
				p[ca] = pa;
				sameColAsParent[ca] = same;
				size[cb] = sb;
			}

		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

	}
}

