// Max = 1 + C(n, 2) + C(n, 4)
// Refer to http://en.wikipedia.org/wiki/Dividing_a_circle_into_areas or
// http://www.arbelos.co.uk/Papers/Chords-regions.pdf
#include <vector>
#include <iostream>
#include <string.h>
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) 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 void DoTest(char* data)
{
if ((!data) || (data[0] == '\0'))
{
cout << 0 << endl;
return;
}
if (data[1] == '\0')
{
int max = -1;
if (data[0] == '0')
max = 1;
else if (data[1] == '1')
max = 1;
else if (data[2] == '2')
max = 2;
else if (data[3] == '3')
max = 8;
if (max > 0)
{
cout << max << endl;
return;
}
}
Integer num(data, strlen(data));
Integer one("1", 1);
Integer two("2", 1);
Integer three("3", 1);
Integer four("4", 1);
Integer result, tmpResult1, tmpResult2, tmpResult3, cn2, cn4;
Integer numMinus1;
num.Minus(one, numMinus1);
num.Multiply(numMinus1, tmpResult1);
tmpResult1.Divide(two, cn2); // Now we have C(n, 2)
num.Minus(two, tmpResult1);
cn2.Multiply(tmpResult1, tmpResult2);
num.Minus(three, tmpResult1);
tmpResult2.Multiply(tmpResult1, tmpResult3);
tmpResult3.Divide(three, tmpResult2);
tmpResult2.Divide(four, cn4);
one.Add(cn2, tmpResult1);
tmpResult1.Add(cn4, result);
result.Print();
cout << endl;
}
#define MAX_BUF_SIZE 4096
static void Test()
{
int cnt;
char buf[MAX_BUF_SIZE];
cin >> cnt;
for (int i = 0; i < cnt; ++i)
{
cin >> buf;
DoTest(buf);
}
}
int main(int argc, char* argv[])
{
Test();
return 0;
}