#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;
}