#include <iostream>
#include <functional>
using namespace std;
template<typename A, typename B>
using F = function<A(B)>;
// Church numeral:
template<typename A>
using CN = F<F<A, A>, F<A, A>>;
int churchToInt(CN<int>);
template<typename A>
CN<A> zero() {
return [](F<A,A>) -> F<A,A> {
return [](A i) -> A {return i;};
};
};
template<typename A>
CN<A> inc(CN<A> n) {
return [=](F<A,A> f) -> F<A,A> {
return [=](A a) -> A {
return n(f)(f(a));
};
};
}
template<typename A>
CN<A> operator*(CN<A> a, CN<A> b) {
//printf("I'm %d * %d\n", churchToInt(a), churchToInt(b));
return [=](F<A,A> f) -> F<A,A> {
return b(a(f));
};
}
template<typename A>
CN<A> operator+(CN<A> a, CN<A> b) {
//printf("I'm %d + %d\n", churchToInt(a), churchToInt(b));
return [=](F<A,A> f) -> F<A,A> {
return [=](A i) -> A {
auto i1 = a(f)(i);
return b(f)(i1);
};
};
}
int churchToInt(CN<int> n) {
auto n2 = n([&](int a)->int {return a+1;});
return n2(0);
}
int main() {
auto _0 = zero<int>();
auto _1 = inc<int>(_0);
auto _2 = inc<int>(_1);
auto _3 = inc<int>(_2);
printf("%d\n", churchToInt((_2 + _1) * _3));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+CnVzaW5nIEYgPSBmdW5jdGlvbjxBKEIpPjsKCi8vIENodXJjaCBudW1lcmFsOgp0ZW1wbGF0ZTx0eXBlbmFtZSBBPgp1c2luZyBDTiA9IEY8RjxBLCBBPiwgRjxBLCBBPj47CgppbnQgY2h1cmNoVG9JbnQoQ048aW50Pik7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBBPgpDTjxBPiB6ZXJvKCkgewogcmV0dXJuIFtdKEY8QSxBPikgLT4gRjxBLEE+IHsKICAgIHJldHVybiBbXShBIGkpIC0+IEEge3JldHVybiBpO307CiB9Owp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgQT4KQ048QT4gaW5jKENOPEE+IG4pIHsKICAgIHJldHVybiBbPV0oRjxBLEE+IGYpIC0+IEY8QSxBPiB7CiAgICAgICAgcmV0dXJuIFs9XShBIGEpIC0+IEEgewogICAgICAgICAgICByZXR1cm4gbihmKShmKGEpKTsKICAgICAgICB9OwogICAgfTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgQT4KQ048QT4gb3BlcmF0b3IqKENOPEE+IGEsIENOPEE+IGIpIHsKICAgIC8vcHJpbnRmKCJJJ20gJWQgKiAlZFxuIiwgY2h1cmNoVG9JbnQoYSksIGNodXJjaFRvSW50KGIpKTsKICAgIHJldHVybiBbPV0oRjxBLEE+IGYpIC0+IEY8QSxBPiB7CiAgICAgICAgcmV0dXJuIGIoYShmKSk7CiAgICB9Owp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBBPgpDTjxBPiBvcGVyYXRvcisoQ048QT4gYSwgQ048QT4gYikgewogICAgLy9wcmludGYoIkknbSAlZCArICVkXG4iLCBjaHVyY2hUb0ludChhKSwgY2h1cmNoVG9JbnQoYikpOwogICAgcmV0dXJuIFs9XShGPEEsQT4gZikgLT4gRjxBLEE+IHsKICAgICAgICByZXR1cm4gWz1dKEEgaSkgLT4gQSB7CiAgICAgICAgICAgIGF1dG8gaTEgPSBhKGYpKGkpOwogICAgICAgICAgICByZXR1cm4gYihmKShpMSk7CiAgICAgICAgfTsKICAgIH07Cn0KCmludCBjaHVyY2hUb0ludChDTjxpbnQ+IG4pIHsKICAgIGF1dG8gbjIgPSBuKFsmXShpbnQgYSktPmludCB7cmV0dXJuIGErMTt9KTsKICAgIHJldHVybiBuMigwKTsKfQoKaW50IG1haW4oKSB7CiAgICBhdXRvIF8wID0gemVybzxpbnQ+KCk7CiAgICBhdXRvIF8xID0gaW5jPGludD4oXzApOwogICAgYXV0byBfMiA9IGluYzxpbnQ+KF8xKTsKICAgIGF1dG8gXzMgPSBpbmM8aW50PihfMik7CiAgICBwcmludGYoIiVkXG4iLCBjaHVyY2hUb0ludCgoXzIgKyBfMSkgKiBfMykpOwogICAgcmV0dXJuIDA7Cn0=