import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.lang.reflect.Array; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; import java.util.Queue; import java.util.Random; import java.util.function.IntBinaryOperator; import java.util.function.IntFunction; import java.util.function.IntToDoubleFunction; import java.util.function.IntToLongFunction; import java.util.function.IntUnaryOperator; import java.util.function.LongBinaryOperator; import java.util.function.Predicate; import java.util.function.ToIntFunction; import java.util.random.RandomGenerator; import java.util.stream.IntStream; import java.util.stream.Stream; public class Main { static MyPrintWriter pw = MyPrintWriter.getInstance(); static FastScanner sc = FastScanner.getInstance(); public static void main(String[] args) throws IOException { Thread.setDefaultUncaughtExceptionHandler((t, e) -> System.exit(1)); new Main().run(); // new Main().test(); pw.flush(); } void run() { ImplicitDigraph g = new ImplicitDigraph() { // 0112を禁止 @Override public Iterable nextStates(int[] v) { ArrayList list = new ArrayList<>(); for (int i = 0; i < (v.length - 1); i++) { if (v[i] == v[i + 1]) { continue; } int[] u = v.clone(); { var tmp = u[i]; u[i] = u[i + 1]; u[i + 1] = tmp; } if (check(u)) { list.add(u); } } return list; } boolean check(int[] v) { for (int i = 0; (i + 3) < v.length; i++) { if ((((v[i] == 0) && (v[i + 1] == 1)) && (v[i + 2] == 1)) && (v[i + 3] == 2)) { return false; } } return true; } }; int Q = sc.nextInt(); for (int TEST = 0; TEST < Q; TEST++) { char[] S = sc.next().toCharArray(); char[] T = sc.next().toCharArray(); var A = f(S); var B = f(T); pw.printlnYesNo(solve(A, B)); } // 11201 // 11021 // 10121 // 10211 // 01211 // 01121 // for (int T = 0; T < 10000; T++) { // int n=7; // int[]a=ArrayUtils.randomIntArray(0, 3, n); // int[]b=ArrayUtils.randomIntArray(0, 3, n); // if(!check(a)||!check(b))continue; // boolean ans=solve(a.clone(), b.clone()); // boolean naive=g.onPath(a.clone(), b.clone()); // if(ans != naive) { // tr(a, b); // tr((int[])g.reachables(a).fold((U, V) -> Arrays.compare(U, V) < 0 ? U : V)); // tr((int[])g.reachables(b).fold((U, V) -> Arrays.compare(U, V) < 0 ? U : V)); // tr("ans,naive",ans, naive); // var path=g.path(a, b); // for (var v : path) { // tr("v",v); // } // throw new AssertionError(); // /11221 // } // [0,1][1][1,2] と分けられる // // int LEN=8; // OpenHashSetset=new OpenHashSet(); // for (var A : Itertools.product(IntStream.range(0, 3).toArray(), LEN)) { // boolean f=false; // for (var a : Itertools.permutations(A.clone())) { // if(!check(a))continue; // var X=g.reachables(a.clone()); // if(set.contains(a))continue; // var min=a; // for (var x : X) { // set.add(x.clone()); // f=true; // if(Arrays.compare(min, x) > 0) min=x; // } // tr(min); // } // if(f)System.out.println(); // } } boolean check(int[] v) { for (int i = 0; (i + 3) < v.length; i++) { if ((((v[i] == 0) && (v[i + 1] == 1)) && (v[i + 2] == 1)) && (v[i + 3] == 2)) { return false; } } return true; } int type(int[] S) { int a = ArrayUtils.indexOf(S, 2); int b = ArrayUtils.lastIndexOf(S, 0); if (a < b) { return 1; } for (int i = 0; (i + 1) < S.length; i++) { if (S[i] == 0) { int j = i; while (((j + 1) < S.length) && (S[j + 1] == 1)) { j++; } if ((((j + 1) < S.length) && ((j - i) >= 2)) && (S[j + 1] == 2)) { return 0; } i = j; } } return 1; } boolean solve(int[] S, int[] T) { int[] cnt0 = new int[10]; int[] cnt1 = new int[10]; for (int v : S) { cnt0[v]++; } for (int v : T) { cnt1[v]++; } if (!Arrays.equals(cnt0, cnt1)) { return false; } if (((cnt0[0] == 0) || (cnt0[1] <= 1)) || (cnt0[2] == 0)) { return true; } return type(S) == type(T); } int[] f(char[] a) { int[] ret = new int[a.length]; for (int i = 0; i < a.length; i++) { if (a[i] == 'g') { ret[i] = 0; } if (a[i] == 'o') { ret[i] = 1; } if (a[i] == 'd') { ret[i] = 2; } } return ret; } } class ArrayUtils { /** * a[i]=vとなる最初のindexを返す。存在しないときは-1を返す。 * * @param v * @param a * @return */ public static int indexOf(int[] a, int v) { int i = 0; while ((i < a.length) && (a[i] != v)) { ++i; } if (i == a.length) { return -1; } return i; } /** * a[i]=vとなる最後のindexを返す。存在しないときは-1を返す。 * * @param v * @param a * @return */ public static int lastIndexOf(int[] a, int v) { int i = a.length - 1; while ((i >= 0) && (a[i] != v)) { --i; } return i; } } class FastScanner { private static FastScanner instance = null; private final InputStream in = System.in; private final byte[] buffer = new byte[1 << 16]; private int ptr = 0; private int buflen = 0; private FastScanner() { } public static FastScanner getInstance() { if (instance == null) { instance = new FastScanner(); } return instance; } private boolean hasNextByte() { if (ptr < buflen) { return true; } ptr = 0; try { buflen = in.read(buffer); } catch (IOException e) { e.printStackTrace(); } return buflen > 0; } private int readByte() { if (hasNextByte()) { return buffer[ptr++]; } else { return -1; } } private boolean isPrintableChar(int c) { return (33 <= c) && (c <= 126); } public boolean hasNext() { while (hasNextByte() && (!isPrintableChar(buffer[ptr]))) { ptr++; } return hasNextByte(); } public String next() { if (!hasNext()) { throw new NoSuchElementException(); } StringBuilder sb = new StringBuilder(); int b = readByte(); while (isPrintableChar(b)) { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } public long nextLong() { if (!hasNext()) { throw new NoSuchElementException(); } long n = 0; boolean minus = false; int b = readByte(); if (b == '-') { minus = true; b = readByte(); } while ((b >= '0') && (b <= '9')) { // n = n * 10 + (b - '0'); n = ((n << 1) + (n << 3)) + (b - '0'); b = readByte(); } return minus ? -n : n; } public int nextInt() { return ((int) (nextLong())); } } class Hash { public interface Strategy { int hashCode(K o); boolean equals(K a, K b); } public static Strategy defaultStrategy() { return new Strategy() { @Override public int hashCode(K o) { if (o instanceof int[]) { return Arrays.hashCode(((int[]) (o))); } if (o instanceof long[]) { return Arrays.hashCode(((long[]) (o))); } if (o instanceof Long x) { x ^= x >>> 33; x *= 0xff51afd7ed558ccdL; x ^= x >>> 33; x *= 0xc4ceb9fe1a85ec53L; x ^= x >>> 33; return x.intValue(); } return o.hashCode(); } @Override public boolean equals(K a, K b) { if ((a instanceof int[]) && (b instanceof int[])) { return Arrays.equals(((int[]) (a)), ((int[]) (b))); } if ((a instanceof long[]) && (b instanceof long[])) { return Arrays.equals(((long[]) (a)), ((long[]) (b))); } return a.equals(b); } }; } } /** * 暗黙的に定義された有向グラフを扱うための抽象クラス。 * *

頂点集合が膨大または未知であり、隣接リストが動的に生成される場合に使用する。 * 到達可能な範囲の探索や、各種グラフアルゴリズムをサポートする。

* * @param * 頂点(状態)の型。{@code equals} と {@code hashCode} が適切に実装されている必要がある。 */ abstract class ImplicitDigraph { /** * ハッシュ戦略。 */ protected final Hash.Strategy strategy; /** * デフォルトのハッシュ戦略を使用するコンストラクタ。 */ protected ImplicitDigraph() { this(Hash.defaultStrategy()); } /** * 指定されたハッシュ戦略を使用するコンストラクタ。 * * @param strategy * ハッシュ戦略 */ protected ImplicitDigraph(Hash.Strategy strategy) { this.strategy = strategy; } /** * 指定された頂点から遷移可能な次の頂点の集合を返す。 * * @param v * 現在の頂点 * @return 次の頂点のイテラブル */ public abstract Iterable nextStates(V v); } class MyPrintWriter extends PrintWriter { private static MyPrintWriter instance = null; private MyPrintWriter() { super(System.out); } public static MyPrintWriter getInstance() { if (instance == null) { instance = new MyPrintWriter(); } return instance; } public void printlnYesNo(boolean flag) { println(flag ? "Yes" : "No"); } } // --- Original Code --- // import java.io.IOException; // import java.util.ArrayList; // import java.util.Arrays; // // import library.tools.FastScanner; // import library.tools.MergeFiles; // import library.tools.MyPrintWriter; // import library.util.ArrayUtils; // import library.util.collections.IntArrayList; // import library.util.graph.ImplicitDigraph; // // public class Main { // static MyPrintWriter pw = MyPrintWriter.getInstance(); // static FastScanner sc = FastScanner.getInstance(); // // public static void main(String[] args) throws IOException { // new Main().run(); // // new Main().test(); // pw.flush(); // MergeFiles.export(); // } // // void run() { // ImplicitDigraphg=new ImplicitDigraph() { // //0112を禁止 // @Override // public Iterable nextStates(int[] v) { // ArrayListlist=new ArrayList<>(); // for (int i = 0; i < v.length-1; i++) { // if(v[i]==v[i+1])continue; // int[]u=v.clone(); // { // var tmp = u[i]; // u[i] = u[i+1]; // u[i+1] = tmp; // } // if (check(u)) list.add(u); // } // return list; // } // // boolean check(int[] v) { // for (int i = 0; i+3 < v.length; i++) { // if(v[i]==0&&v[i+1]==1&&v[i+2]==1&&v[i+3]==2) return false; // } // return true; // } // }; // int Q=sc.nextInt(); // for (int TEST = 0; TEST < Q; TEST++) { // char[]S=sc.next().toCharArray(); // char[]T=sc.next().toCharArray(); // var A=f(S); // var B=f(T); // pw.printlnYesNo(solve(A, B)); // } // //11201 // //11021 // //10121 // //10211 // //01211 // //01121 // // // for (int T = 0; T < 10000; T++) { // // int n=7; // // int[]a=ArrayUtils.randomIntArray(0, 3, n); // // int[]b=ArrayUtils.randomIntArray(0, 3, n); // // if(!check(a)||!check(b))continue; // // boolean ans=solve(a.clone(), b.clone()); // // boolean naive=g.onPath(a.clone(), b.clone()); // // if(ans != naive) { // // tr(a, b); // // tr((int[])g.reachables(a).fold((U, V) -> Arrays.compare(U, V) < 0 ? U : V)); // // tr((int[])g.reachables(b).fold((U, V) -> Arrays.compare(U, V) < 0 ? U : V)); // // tr("ans,naive",ans, naive); // // var path=g.path(a, b); // // for (var v : path) { // // tr("v",v); // // } // // throw new AssertionError(); // // }//11221 // // } // // // [0,1][1][1,2] と分けられる // // // // // int LEN=8; // // OpenHashSetset=new OpenHashSet(); // // for (var A : Itertools.product(IntStream.range(0, 3).toArray(), LEN)) { // // boolean f=false; // // for (var a : Itertools.permutations(A.clone())) { // // if(!check(a))continue; // // var X=g.reachables(a.clone()); // // if(set.contains(a))continue; // // var min=a; // // for (var x : X) { // // set.add(x.clone()); // // f=true; // // if(Arrays.compare(min, x) > 0) min=x; // // } // // tr(min); // // } // // if(f)System.out.println(); // // } // } // // boolean check(int[] v) { // for (int i = 0; i+3 < v.length; i++) { // if(v[i]==0&&v[i+1]==1&&v[i+2]==1&&v[i+3]==2) return false; // } // return true; // } // // int type(int[]S) { // int a=ArrayUtils.indexOf(S, 2); // int b=ArrayUtils.lastIndexOf(S, 0); // if (a < b) return 1; // for (int i = 0; i+1 < S.length; i++) { // if(S[i]==0) { // int j=i; // while(j+1=2 && S[j+1]==2) return 0; // i=j; // } // } // return 1; // } // // boolean solve(int[]S, int[] T) { // int[]cnt0=new int[10]; // int[]cnt1=new int[10]; // for (int v : S)cnt0[v]++; // for (int v : T)cnt1[v]++; // if(!Arrays.equals(cnt0, cnt1))return false; // if(cnt0[0]==0||cnt0[1]<=1||cnt0[2]==0) return true; // return type(S)==type(T); // } // // int[] f(char[] a) { // int[]ret=new int[a.length]; // for (int i = 0; i < a.length; i++) { // if(a[i]=='g')ret[i]=0; // if(a[i]=='o')ret[i]=1; // if(a[i]=='d')ret[i]=2; // } // return ret; // } // // void tr(Object... objects) { // System.out.println(Arrays.deepToString(objects)); // } // } //