Problem:
Problem B: Equals are Equals

Mr. Simpson got up with a slight feeling of tiredness. It was the start of another day of hard work. A bunch of papers were waiting for his inspection on his desk in his office. The papers contained his students' answers to questions in his Math class, but the answers looked as if they were just stains of ink.

His headache came from the ``creativity'' of his students. They provided him a variety of ways to answer each problem. He has his own answer to each problem, which is correct, of course, and the best from his aesthetic point of view.

Some of his students wrote algebraic expressions equivalent to the expected answer, but many of them look quite different from Mr. Simpson's answer in terms of their literal forms. Some wrote algebraic expressions not equivalent to his answer, but they look quite similar to it. Only a few of the students' answers were exactly the same as his.

It is his duty to check if each expression is mathematically equivalent to the answer he has prepared. This is to prevent expressions that are equivalent to his from being marked as ``incorrect'', even if they are not acceptable to his aesthetic moral.

He had now spent five days checking the expressions. Suddenly, he stood up and yelled, ``I've had enough! I must call for help.''

Your job is to write a program to help Mr. Simpson to judge if each answer is equivalent to the ``correct'' one. Algebraic expressions written on the papers are multi-variable polynomials over variable symbols a, b,..., z with integer coefficients, e.g.,

(a + b2)(a - b2), ax2 +2bx + c and (x2 +5x + 4)(x2 + 5x + 6) + 1.

Mr. Simpson will input every answer expression as it is written on the papers; he promises you that an algebraic expression he inputs is a sequence of terms separated by additive operators `+' and `-', representing the sum of the terms with those operators, if any; a term is a juxtaposition of multiplicands, representing their product; and a multiplicand is either (a) a non-negative integer as a digit sequence in decimal, (b) a variable symbol (one of the lowercase letters `a' to `z'), possibly followed by a symbol `^' and a non-zero digit, which represents the power of that variable, or (c) a parenthesized algebraic expression, recursively. Note that the operator `+' or `-' appears only as a binary operator and not as a unary operator to specify the sing of its operand.

He says that he will put one or more space characters before an integer if it immediately follows another integer or a digit following the symbol `^'. He also says he may put spaces here and there in an expression as an attempt to make it readable, but he will never put a space between two consecutive digits of an integer. He remarks that the expressions are not so complicated, and that any expression, having its `-'s replaced with `+'s, if any, would have no variable raised to its 10th power, nor coefficient more than a billion, even if it is fully expanded into a form of a sum of products of coefficients and powered variables.

Input

The input to your program is a sequence of blocks of lines. A block consists of lines, each containing an expression, and a terminating line. After the last block, there is another terminating line. A terminating line is a line solely consisting of a period symbol.

The first expression of a block is one prepared by Mr. Simpson; all that follow in a block are answers by the students. An expression consists of lowercase letters, digits, operators `+', `-' and `^', parentheses `(' and `)', and spaces. A line containing an expression has no more than 80 characters.

Output

Your program should produce a line solely consisting of ``yes'' or ``no'' for each answer by the students corresponding to whether or not it is mathematically equivalent to the expected answer. Your program should produce a line solely containing a period symbol after each block.

Sample Input

a+b+c
(a+b)+c
a- (b-c)+2
.
4ab
(a - b) (0-b+a) - 1a ^ 2 - b ^ 2
2 b 2 a
.
108 a
2 2 3 3 3 a
4 a^1 27
.
.

Output for the Sample Input

yes
no
.
no
yes
.
yes
yes
.

Solution in JAVA (judge verdict: Accepted)

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

//Equals are Equals
public class Main{

	char[] s;
	int id;
	
	class P{
		Map<String, Integer> c;
		int c0;
		public P() {
			c = new HashMap<String, Integer>();
			c0 = 0;
		}
		boolean eq(P p){
//			Set<String> set = new HashSet<String>();
//			for(String t:c.keySet())if(c.get(t)==0)set.add(t);
//			for(String t:set)c.remove(t);
//			set = new HashSet<String>();
//			for(String t:p.c.keySet())if(p.c.get(t)==0)set.add(t);
//			for(String t:set)p.c.remove(t);
			if(c.size()!=p.c.size()||c0!=p.c0){
//				System.out.println("DIFF22:" + c.size() + " " + p.c.size() + " " + c0 + " "  +p.c0);
				return false;
			}
			for(String t:c.keySet())if(!p.c.containsKey(t)||c.get(t).intValue()!=p.c.get(t).intValue()){
//				System.out.println("DIFF:" + c.get(t)+" "+p.c.get(t));
				return false;
			}
			return true;
		}
		P add(P p){
//			System.out.println("ADD:" + this + " " + p);
			P r = new P();
			for(String t:c.keySet()){
				if(p.c.containsKey(t))r.c.put(t, c.get(t)+p.c.get(t));
				else r.c.put(t, c.get(t));
			}
			for(String t:p.c.keySet()){
				if(!c.containsKey(t))r.c.put(t, p.c.get(t));
			}
			r.c0 = c0+p.c0;
			Set<String> set = new HashSet<String>();
			for(String t:r.c.keySet())if(r.c.get(t)==0)set.add(t);
			for(String t:set)r.c.remove(t);
//			System.out.println("R*" + r);
			return r;
		}
		P sub(P p){
//			System.out.println("SUB:" + this + " " + p);
			P r = new P();
			for(String t:c.keySet()){
				if(p.c.containsKey(t))r.c.put(t, c.get(t)-p.c.get(t));
				else r.c.put(t, c.get(t));
			}
			for(String t:p.c.keySet()){
				if(!c.containsKey(t))r.c.put(t, -p.c.get(t));
			}
			r.c0 = c0-p.c0;
			Set<String> set = new HashSet<String>();
			for(String t:r.c.keySet())if(r.c.get(t)==0)set.add(t);
			for(String t:set)r.c.remove(t);
//			System.out.println("R*" + r);
			return r;
		}
		P mul(P p){
//			System.out.println("MUL:" + this + " " + p);
			P r = new P();
			for(String s:c.keySet())for(String t:p.c.keySet()){
				char[] x = (s+t).toCharArray();
				Arrays.sort(x);
				String v = new String(x);
				if(r.c.containsKey(v))r.c.put(v, r.c.get(v)+c.get(s)*p.c.get(t));
				else r.c.put(v, c.get(s)*p.c.get(t));
			}
//			System.out.println("R1:" + r);
			for(String s:c.keySet()){
				if(r.c.containsKey(s))r.c.put(s, r.c.get(s)+p.c0*c.get(s));
				else r.c.put(s, p.c0*c.get(s));
			}
			for(String s:p.c.keySet()){
				if(r.c.containsKey(s))r.c.put(s, r.c.get(s)+c0*p.c.get(s));
				else r.c.put(s, c0*p.c.get(s));
			}
			r.c0 += c0*p.c0;
			Set<String> set = new HashSet<String>();
			for(String t:r.c.keySet())if(r.c.get(t)==0)set.add(t);
			for(String t:set)r.c.remove(t);
//			System.out.println("R*" + r);
			return r;
		}
		P pow(int k){
//			System.out.println("POW:" + this + " " + k);
			P r = new P();
			r.c0 = 1;
			while(k--!=0)r = r.mul(this);
//			System.out.println("R*" + r);
			Set<String> set = new HashSet<String>();
			for(String t:r.c.keySet())if(r.c.get(t)==0)set.add(t);
			for(String t:set)r.c.remove(t);
			return r;
		}
		@Override
		public String toString() {
			String r = "";
			for(String t:c.keySet())r+=" "+c.get(t)+t;
			r+=" "+c0;
			return r;
		}
	}
	
	char get(){
//		System.out.println(s[id]);
		return s[id++];
	}
	char next(){
		while(s[id]==' ')id++;
//		System.out.println(s[id]);
		return s[id++];
	}
	
	P exp(){
		P r = term();
		char ch = next(); 
		while(ch=='+'||ch=='-'){
//			System.out.println("CH:" + ch);
			P f = term();
//			System.out.println(f);
			if(ch=='+')r = r.add(f);
			else r = r.sub(f);
//			System.out.println("RRR:" + r);
			ch = next();
		}
		id--;
		return r;
	}
	
	P term(){
		P r = fact();
		char ch = next();
		while(Character.isDigit(ch)||Character.isLowerCase(ch)||ch=='('){
//			System.out.println("Term char:" + ch);
			id--;
			P f = fact();
//			System.out.println("F:" + f);
			r = r.mul(f);
//			System.out.println("MUL : " + r);
			ch = next();
		}
		id--;
//		System.out.println("Term end with: " + s[id]);
		return r;
	}
	
	P fact(){
		char ch = next();
//		System.out.println("INIT: " + ch);
		P r = new P();
		if(ch=='('){
			r = exp();
			next();
		}
		else if(Character.isLowerCase(ch))r.c.put(ch+"", 1);
		else if(Character.isDigit(ch)){
			int x = ch-'0';
			for(;;){
				ch = get();
				if(!Character.isDigit(ch)){
					id--;break;
				}
				x = x*10 + ch-'0';
			}
//			System.out.println("X:" + x);
			r.c0 = x;
		}
//		System.out.println("R0:" + r);
		ch = next();
		while(ch=='^'){
			int x = next()-'0';
			r = r.pow(x);
			ch = next();
		}
		id--;
//		System.out.println("Fact end with: " + s[id]);
		return r;
	}
	
	void run(){
		Scanner sc = new Scanner(System.in);
		for(;;){
			s = (sc.nextLine()+"$").toCharArray();
			if(s[0]=='.')break;
			id = 0;
			P ans = exp();
//			System.out.println("ANS:" + ans);
			for(;;){
				s = (sc.nextLine()+"$").toCharArray();
				if(s[0]=='.')break;
				id = 0;
				P p = exp();
//				System.out.println("Pol:" + p);
				System.out.println(ans.eq(p)?"yes":"no");
			}
			System.out.println(".");
		}
	}
	
	public static void main(String[] args) {
		new Main().run();
	}
}