#include <vector>
#include <iostream>
using namespace std;
class Integer
{
public:
Integer(char* buf, int len)
{
for (int i = 0; i < len; ++i)
m_data.push_back(buf[i] - '0');
}
Integer() {}
void Print()
{
int cnt = m_data.size();
if (cnt <= 0)
cout << "0";
for (int i = 0; i < cnt; ++i)
cout << m_data[i];
}
void Add(const Integer& other)
{
Integer result;
Add(other, result);
m_data = result.m_data;
}
void Minus(const Integer& other)
{
Integer result;
Minus(other, result);
m_data = result.m_data;
}
void Multiply(const Integer& other)
{
Integer result;
Multiply(other, result);
m_data = result.m_data;
}
void Divide(const Integer& other)
{
Integer result;
Divide(other, result);
m_data = result.m_data;
}
private:
void Add(const Integer& other, Integer& result) const
{
result.m_data.clear();
int flag = 0;
int i = 0, limit = (other.m_data.size() > m_data.size()) ? other.m_data.size() : m_data.size();
while(i < limit)
{
int num1 = (i < m_data.size()) ? m_data[m_data.size() - 1 - i] : 0;
int num2 = (i < other.m_data.size()) ? other.m_data[other.m_data.size() - 1 - i] : 0;
int sum = num1 + num2 + flag;
flag = sum / 10;
result.m_data.push_back(sum % 10);
++i;
}
if (flag > 0)
result.m_data.push_back(flag);
result.ShrinkAndInvert();
}
void Minus(const Integer& other, Integer& result) const
{
result.m_data.clear();
int flag = 0;
int i = 0, limit = (other.m_data.size() > m_data.size()) ? other.m_data.size() : m_data.size();
while(i < limit)
{
int num1 = (i < m_data.size()) ? m_data[m_data.size() - 1 - i] : 0;
int num2 = (i < other.m_data.size()) ? other.m_data[other.m_data.size() - 1 - i] : 0;
int left = num1 - flag - num2;
if (left < 0)
{
flag = 1;
left += 10;
}
else
flag = 0;
result.m_data.push_back(left);
++i;
}
if (flag < 0)
result.m_data.push_back(9);
result.ShrinkAndInvert();
}
void Multiply(const Integer& other, Integer& result) const
{
result.m_data.clear();
for (int i = other.m_data.size() - 1; i >= 0; --i)
{
Integer tmp, sum;
Multiply(other.m_data[i], tmp, other.m_data.size() - i - 1);
result.Add(tmp, sum);
result = sum;
}
}
void Multiply(const int n, Integer& result, int shift) const
{
result.m_data.clear();
for (int i = 0; i < shift; ++i)
result.m_data.push_back(0);
int flag = 0;
for (int i = m_data.size() - 1; i >= 0; --i)
{
int tmp = m_data[i] * n + flag;
flag = tmp / 10;
result.m_data.push_back(tmp % 10);
}
if (flag > 0)
result.m_data.push_back(flag);
result.ShrinkAndInvert();
}
void Divide(const Integer& other, Integer& result) const
{
result.m_data.clear();
if (operator == (other))
{
result.m_data.push_back(1);
return;
}
if (!(operator > (other)))
return;
int sizeDev = m_data.size() - other.m_data.size();
Integer tmp = (*this);
Integer resultTmp1, resultTmp2;
for (int i = sizeDev; i >= 0; --i)
{
Integer tmp1, tmp2;
other.Multiply(1, tmp1, i);
int sum = 0;
while(true)
{
if (tmp >= tmp1)
{
tmp.Minus(tmp1, tmp2);
++sum;
tmp = tmp2;
}
else
break;
}
resultTmp1.m_data.clear();
if (sum > 0)
{
for (int j = 0; j < i; ++j)
resultTmp1.m_data.push_back(0);
resultTmp1.m_data.push_back(sum);
resultTmp1.ShrinkAndInvert();
}
result.Add(resultTmp1, resultTmp2);
result = resultTmp2;
}
}
private:
void ShrinkAndInvert()
{
while(m_data.size() != 0)
{
if (m_data[m_data.size() - 1] == 0)
m_data.pop_back();
else
break;
}
int cnt = m_data.size();
for (int i = 0; i < cnt / 2; ++i)
{
int tmp = m_data[i];
m_data[i] = m_data[cnt - 1 - i];
m_data[cnt - 1 - i] = tmp;
}
}
bool operator > (const Integer& other) const
{
if (m_data.size() > other.m_data.size())
return true;
if (m_data.size() < other.m_data.size())
return false;
for (int i = 0; i < m_data.size(); ++i)
if (m_data[i] < other.m_data[i])
return false;
else if (m_data[i] > other.m_data[i])
return true;
return false;
}
bool operator == (const Integer& other) const
{
if (m_data.size() != other.m_data.size())
return false;
for (int i = 0; i < m_data.size(); ++i)
if (m_data[i] != other.m_data[i])
return false;
return true;
}
bool operator >= (const Integer& other) const
{
return ((operator > (other)) || (operator == (other)));
}
private:
vector<int> m_data;
};
static Integer* GetResult(int n, vector<Integer*>& results)
{
if (results.size() > n)
return results[n];
Integer* finalResult = NULL;
if (n < 1)
{
finalResult = new Integer("1", 1);
}
if (n >= 1)
{
finalResult = new Integer("0", 1);
Integer* result_n_1 = GetResult(n-1, results);
finalResult->Add(*result_n_1);
finalResult->Add(*result_n_1);
}
if (n >= 2)
{
Integer* result_n_2 = GetResult(n-2, results);
finalResult->Add(*result_n_2);
}
if (n >= 3)
{
Integer* result_n_3 = GetResult(n-3, results);
finalResult->Add(*result_n_3);
}
results.push_back(finalResult);
return finalResult;
}
static void DoTest(int n, vector<Integer*>& results)
{
Integer* result = GetResult(n, results);
result->Print();
}
static void Test()
{
vector<Integer*> results;
results.push_back(new Integer("1", 1));
int n;
while(cin >> n)
{
DoTest(n, results);
cout << endl;
}
vector<Integer*>::iterator iter = results.begin();
while (iter != results.end())
{
delete (*iter);
++iter;
}
}
int main(int argc, char* argv[])
{
Test();
return 0;
}