#include <iostream>
class A1;
class A2;
class A {
public:
virtual void M(A &) = 0;
virtual void M(A1 &) = 0;
virtual void M(A2 &) = 0;
};
class A1 : public A {
public:
virtual void M(A &a) { a.M(*this); }
virtual void M(A1 &a) { std::cout << "A1 <- A1\n"; }
virtual void M(A2 &a) { std::cout << "A2 <- A1\n"; }
};
class A2 : public A {
public:
virtual void M(A &a) { a.M(*this); }
virtual void M(A1 &a) { std::cout << "A1 <- A2\n"; }
virtual void M(A2 &a) { std::cout << "A2 <- A2\n"; }
};
int main()
{
A1 a1;
A2 a2;
A &b1 = a1;
A &b2 = a2;
b1.M(b1);
b1.M(b2);
b2.M(b1);
b2.M(b2);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKY2xhc3MgQTE7CmNsYXNzIEEyOwoKY2xhc3MgQSB7CnB1YmxpYzoKICAgIHZpcnR1YWwgdm9pZCBNKEEgJikgPSAwOwogICAgdmlydHVhbCB2b2lkIE0oQTEgJikgPSAwOwogICAgdmlydHVhbCB2b2lkIE0oQTIgJikgPSAwOwp9OwogICAgCmNsYXNzIEExIDogcHVibGljIEEgewpwdWJsaWM6CiAgICB2aXJ0dWFsIHZvaWQgTShBICZhKSB7IGEuTSgqdGhpcyk7IH0KICAgIHZpcnR1YWwgdm9pZCBNKEExICZhKSB7IHN0ZDo6Y291dCA8PCAiQTEgPC0gQTFcbiI7IH0KICAgIHZpcnR1YWwgdm9pZCBNKEEyICZhKSB7IHN0ZDo6Y291dCA8PCAiQTIgPC0gQTFcbiI7IH0KfTsKICAgIApjbGFzcyBBMiA6IHB1YmxpYyBBIHsKcHVibGljOgogICAgdmlydHVhbCB2b2lkIE0oQSAmYSkgeyBhLk0oKnRoaXMpOyB9CiAgICB2aXJ0dWFsIHZvaWQgTShBMSAmYSkgeyBzdGQ6OmNvdXQgPDwgIkExIDwtIEEyXG4iOyB9CiAgICB2aXJ0dWFsIHZvaWQgTShBMiAmYSkgeyBzdGQ6OmNvdXQgPDwgIkEyIDwtIEEyXG4iOyB9Cn07CgppbnQgbWFpbigpCnsKICAgIEExIGExOwogICAgQTIgYTI7CgogICAgQSAmYjEgPSBhMTsKICAgIEEgJmIyID0gYTI7CgogICAgYjEuTShiMSk7CiAgICBiMS5NKGIyKTsKICAgIGIyLk0oYjEpOwogICAgYjIuTShiMik7Cn0=