public Polynomial gcd(Polynomial x) throws Exception {
        Polynomial a = monic();
        Polynomial b = x.monic();
    
        while (true) {
            if (a.degree() < b.degree()) {
                Polynomial t = a;
                a = b;
                b = t;
            }
            if (b.degree() < 0) return a;   // gcd(a,0) == a
            Polynomial z = x().pow(a.degree() - b.degree());
            a = a.sub(b.mul(z)).monic();    // cancel the highest degree of a
        }
    }