#include <iostream>
#include <type_traits>
using namespace std;

typedef unsigned long mySize;

//default
template <class P, class dummy = void>
class T{
	public:
   static P f(){return 0;}
};

//int
template <>
class T<int,void> {
	public:
   static int f(){return 1;}
};

//unsigned long
template <>
class T<unsigned long, void> {
	public:
   static unsigned long f(){return 2;}
};

template <class P>
class T<P, typename enable_if<is_same<P, mySize>::value && !is_same<P, unsigned long>::value, void>::type> {
	public:
   static P f(){return 3;}
};

int main() {
	cout << T<int>::f() << endl;
	cout << T<unsigned long>::f() << endl;
	cout << T<mySize>::f() << endl;
	return 0;
}