Problem: Amugae is in a very large round corridor. The corridor consists of two areas. The inner area is equally divided by n sectors, and the outer area is equally divided by m sectors. A wall exists between each pair of sectors of same area (inner or outer), but there is no wall between the inner area and the outer area. A wall always exists at the 12 o'clock position.

<image>

The inner area's sectors are denoted as (1,1), (1,2), ..., (1,n) in clockwise direction. The outer area's sectors are denoted as (2,1), (2,2), ..., (2,m) in the same manner. For a clear understanding, see the example image above.

Amugae wants to know if he can move from one sector to another sector. He has q questions.

For each question, check if he can move between two given sectors.

Input

The first line contains three integers n, m and q (1 ≤ n, m ≤ 10^{18}, 1 ≤ q ≤ 10^4) — the number of sectors in the inner area, the number of sectors in the outer area and the number of questions.

Each of the next q lines contains four integers s_x, s_y, e_x, e_y (1 ≤ s_x, e_x ≤ 2; if s_x = 1, then 1 ≤ s_y ≤ n, otherwise 1 ≤ s_y ≤ m; constraints on e_y are similar). Amague wants to know if it is possible to move from sector (s_x, s_y) to sector (e_x, e_y).

Output

For each question, print "YES" if Amugae can move from (s_x, s_y) to (e_x, e_y), and "NO" otherwise.

You can print each letter in any case (upper or lower).

Example

Input


4 6 3
1 1 2 3
2 6 1 2
2 6 2 4


Output


YES
NO
YES

Note

Example is shown on the picture in the statement.

Solution (in JAVA):

Solution:
import java.io.*;
import java.math.BigInteger;
import java.util.*;

import javax.swing.plaf.synth.SynthSeparatorUI;
public class Problem3 {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	public static void main(String[] args) throws IOException, InterruptedException {
		long n=sc.nextLong();
		long m=sc.nextLong();
		long g= gcd(n, m);
		n/=g;
		m/=g;
		int q=sc.nextInt();
		while(q-->0) {
			long sx=sc.nextInt();
			long sy=sc.nextLong()-1;
			long ex=sc.nextInt();
		     long ey=sc.nextLong()-1;
			if(sx==1&&ex==1) {
			sy=sy/n;
			ey=ey/n;
			}
			else if(sx==1&&ex==2) {
			sy=sy/n;
			ey=ey/m;
			
			}
			else if(sx==2&&ex==1) {
			sy=sy/m;
			ey=ey/n;
			
			}
			else if(sx==2&&ex==2) {
			sy=sy/m;
			ey=ey/m;
			}
			if(sy==ey) {
				System.out.println("YES");
			}
			else {
				System.out.println("NO");
			}
			
		}
	}
	
	private static boolean check(int k, int mid, int a, int b,int n) {
		long normal=n-mid;
		long cost1=1l*normal*1l*b*1l;
		long cost2=1l*mid*1l*a*1l;
		if(cost1+cost2>=k)
		return false;
		else
			return true;
	}
	static long pow(long a, int n,int mod)
	{
		long res = 1;
		while(n != 0)
		{
			if((n & 1) == 1)
				res = (res*(a));
			a *= (a);
			a=a;
			n >>= 1;			
		}
		return res;
	}
	static TreeSet<Integer> primes;
	static int[] isComposite;

	static void sieve(int N)	// O(N log log N) 
	{
		isComposite = new int[N+1];					
		isComposite[0] = isComposite[1] = 1;			// 0 indicates a prime number
		primes = new TreeSet<Integer>();

		for (int i = 2; i <= N; ++i) 					//can loop till i*i <= N if primes array is not needed O(N log log sqrt(N)) 
			if (isComposite[i] == 0) 					//can loop in 2 and odd integers for slightly better performance
			{
				primes.add(i);
				if(1l * i * i <= N)
					for (int j = i * i; j <= N; j += i)	// j = i * 2 will not affect performance too much, may alter in modified sieve
						isComposite[j] = 1;
			}   
	}
	static int INF=(int) 1E9;
	static class Pair{
		int x;
		int y;
		public Pair(int x,int y) {
			this.x=x;
			this.y=y;
		}
		
	}
	public static int[] schuffle(int a[]) {
		for (int i = 0; i < a.length; i++) {
			int x=(int)(Math.random()*a.length);
		int temp=a[x];
		a[x]=a[i];
		a[i]=temp;
		}
		return a;
	}
	static long gcd(long min,long a) {
		if(a==0) {
			return min;
		}
		return gcd(a,min%a);
	}
static int 	factprime(int n,int p) {
	int pow=0;
	for(int i=p ; i<=n ; i=i*p) {
		pow+=n/i;
	}
	return pow;
}
static long power(long x, long y) 
{ 
    long temp; 
    if( y == 0) 
        return 1; 
       
    temp = power(x, y/2); 
    if (y%2 == 0) 
        return ((temp%10)*(temp)%10)%10; 
    else
        return ((x%10)*(temp%10)*(temp%10))%10;
}  
	static ArrayList<Integer> adj[];
static Stack<Integer> st=new Stack<>();
static  boolean visited[];
static void dfs(int i){
	visited[i]=true;
	st.add(i);
	for(int x:adj[i]) {
		if(!visited[x])
			dfs(x);
	}
}


	static  class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream s) {
		br = new BufferedReader(new InputStreamReader(s));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

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

	public int[] nextIntArr(int n) throws IOException {
		int[] arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = nextInt();
		return arr;
	}

	public long[] nextLongArr(int n) throws IOException {
		long[] arr = new long[n];
		for (int i = 0; i < n; i++)
			arr[i] = nextLong();
		return arr;
	}

	public long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	public String nextLine() throws IOException {
		return br.readLine();
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public boolean ready() throws IOException {
		return br.ready();
	}
	public void waitForInput() throws InterruptedException {Thread.sleep(2300);}
}



static class SegmentTree {
	int N; // number of elements in my array after the padding
	int [] array, sTree, lazy; 
	SegmentTree(int []inp){
		N = inp.length - 1;
		array = inp;
		sTree =  new int[N<<1];
		lazy =  new int[N<<1];
		build(1, 1, N);
	}
	void build(int node, int b, int e) {
		if(b == e) {
			//node = b + N - 1
			// update(idx , value)
			// sTree[idx + N - 1] += value
			sTree[node] = array[b];
		}
		else {
			int nodeLeft = node << 1;
			int nodeRight = (node << 1)+1;
			int mid = (b + e) >> 1;
			build(nodeLeft, b , mid);
			build(nodeRight, mid + 1, e);
			sTree[node] = sTree[nodeLeft] + sTree[nodeRight];
		}
	}
	void propagate(int node, int b, int e) {
		int leftChild = node << 1;
		int rightChild = node<<1|1;
		lazy[leftChild] += lazy[node];
		lazy[rightChild] += lazy[node];
		int mid = (b + e)>>1;
		if(lazy[node]%2!=0) {
		sTree[leftChild] = (mid - b + 1)-sTree[leftChild];
		sTree[rightChild] =(e - mid)-sTree[rightChild];
		}
		lazy[node] = 0;
	}
	// add value v for element in position idx in my input array
	//O(log(N))
	void update_point(int idx, int v) {
		int node = idx + N - 1;
		sTree[node] += v;
		while(node > 1) {
			node >>= 1;
			sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
		}
	}
	// O(log(N))
	int query(int i, int j) {
		return query(1, 1, N, i, j); 
	}
	int query(int node, int b, int e, int i, int j) {
		
		
		if(i > e || j < b)
			return 0;
		if(b >= i && e <= j)
			return sTree[node];
		int mid = (b + e) >> 1;
		propagate(node, b, e);
        int q1 = query(node << 1, b, mid, i , j);
		int q2 = query(node<<1|1, mid + 1, e, i, j);
		return q1 + q2;
		
		
	}
	void update_range(int i, int j) { //O(log(N))
		update_range(1, 1, N, i, j); 
	}
	void update_range(int node, int b, int e, int i, int j) {
		if(i > e || j < b)
			return;
		if(b >= i && e <= j) {
			sTree[node] = (e - b + 1)-sTree[node];
			lazy[node]+=1;
		}
		else {
			int mid = (b + e) >> 1;
			propagate(node, b, e);
			update_range(node<<1, b , mid, i, j);
			update_range(node<<1|1, mid+1, e, i, j);
			sTree[node] = sTree[node<<1] + sTree[node<<1|1];
		}
	}
}
}