/* Code by - Navneet Lohia */

#include <bits/stdc++.h>
using namespace std;

#define int             ll
#define ll              long long
#define ull             unsigned long long
#define vi              vector<int>
#define pii             pair<int, int>
#define uii             unordered_map<int, int>
#define endl            "\n"
#define pb              push_back
#define mp              make_pair
#define fr(i,a,n)       for (int i=a;i<n;i++)
#define rf(i,a,n)       for (int i=n-1;i>=a;i--)
#define tt(x)           int x; cin>>x; while(x--)
#define t(x)            int x = 1; while(x--)
#define input(a,n)      for(int i = 0; i < n; i++){ int x; cin >> x; a[i] = x;}
#define print(a,n)      for(int i = 0; i < n; i++){ cout << a[i] << " ";} cout << endl;
#define Print(a)        for(auto it = a.begin() ; it != a.end() ; it++){ cout << *it << " " ;} cout << endl;
#define ps(x,y)         fixed<<setprecision(y)<<x
#define PI              3.1415926536

// Returns count of subarrays of arr with XOR
// value equals to m
long long subarrayXor(int arr[], int n, int m)
{
    long long ans = 0; // Initialize answer to be returned

    // Create a prefix xor-sum array such that
    // xorArr[i] has value equal to XOR
    // of all elements in arr[0 ..... i]
    int *xorArr = new int[n];

    // Create map that stores number of prefix array
    // elements corresponding to a XOR value
    unordered_map<int, int> mp;

    // Initialize first element of prefix array
    xorArr[0] = arr[0];

    // Computing the prefix array.
    for (int i = 1; i < n; i++)
        xorArr[i] = xorArr[i - 1] ^ arr[i];

    // Calculate the answer
    for (int i = 0; i < n; i++)
    {
        // Find XOR of current prefix with m.
        int tmp = m ^ xorArr[i];

        // If above XOR exists in map, then there
        // is another previous prefix with same
        // XOR, i.e., there is a subarray ending
        // at i with XOR equal to m.
        ans = ans + ((long long)mp[tmp]);

        // If this subarray has XOR equal to m itself.
        if (xorArr[i] == m)
            ans++;

        // Add the XOR of this subarray to the map
        mp[xorArr[i]]++;
    }

    // Return total count of subarrays having XOR of
    // elements as given value m
    return ans;
}

// Function for extended Euclidean Algorithm
int gcdExtended(int a, int b, int *x, int *y)
{
    // Base Case
    if (a == 0)
    {
        *x = 0;
        *y = 1;
        return b;
    }

    int x1, y1; // To store results of recursive call
    int gcd = gcdExtended(b % a, a, &x1, &y1);

    // Update x and y using results of
    // recursive call
    *x = y1 - (b / a) * x1;
    *y = x1;

    return gcd;
}

// ax + by = c (Linear Diophantine equation)
bool find_any_solution(int a, int b, int c, int &x0, int &y0, int &g)
{
    g = gcdExtended(abs(a), abs(b), &x0, &y0);
    if (c % g)
    {
        return false;
    }

    x0 *= c / g;
    y0 *= c / g;
    if (a < 0) x0 = -x0;
    if (b < 0) y0 = -y0;
    return true;
}

int maxContiguousSubArray(int *A, int n)
{
    int max_so_far = A[0];
    int curr_max = A[0];

    for (int i = 1; i < n; i++)
    {
        curr_max = max(A[i], curr_max + A[i]);
        max_so_far = max(max_so_far, curr_max);
    }

    return max_so_far;
}

int NcR(int n, int r)
{

    // p holds the value of n*(n-1)*(n-2)...,
    // k holds the value of r*(r-1)...
    long long p = 1, k = 1;

    // C(n, r) == C(n, n-r),
    // choosing the smaller value
    if (n - r < r)
        r = n - r;

    if (r != 0)
    {
        while (r)
        {
            p *= n;
            k *= r;

            // gcd of p, k
            long long m = __gcd(p, k);

            // dividing by gcd, to simplify product
            // division by their gcd saves from the overflow
            p /= m;
            k /= m;

            n--;
            r--;
        }

        // k should be simplified to 1
        // as C(n, r) is a natural number
        // (denominator should be 1 ) .
    }

    else
        p = 1;

    // if our approach is correct p = ans and k =1
    return p;
}

int power(int x, int y )
{
    if ( y == 0 )
        return 1;

    int temp = power(x, y / 2);

    if ( y % 2 == 0 )
        return temp * temp;
    else
        return x * temp * temp;
}

int power(int x, int y, int p)
{
    int res = 1;      // Initialize result

    x = x % p;  // Update x if it is more than or
    // equal to p

    while (y > 0)
    {
        // If y is odd, multiply x with result
        if (y & 1)
            res = (res * x) % p;

        // y must be even now
        y = y >> 1; // y = y/2
        x = (x * x) % p;
    }
    return res;
}

// This functions finds all primes smaller than 'limit'
// using simple sieve of eratosthenes. It also stores
// found primes in vector prime[]
vi simpleSieve(int limit)
{
    // Create a boolean array "mark[0..n-1]" and initialize
    // all entries of it as true. A value in mark[p] will
    // finally be false if 'p' is Not a prime, else true.
    bool mark[limit + 1];
    memset(mark, true, sizeof(mark));
    vi prime;

    for (int p = 2; p * p < limit; p++)
    {
        // If p is not changed, then it is a prime
        if (mark[p] == true)
        {
            // Update all multiples of p
            for (int i = p * 2; i < limit; i += p)
                mark[i] = false;
        }
    }

    // Print all prime numbers and store them in prime
    for (int p = 2; p < limit; p++)
    {
        if (mark[p] == true)
        {
            prime.push_back(p);
        }
    }
    return prime;
}

// Prints all prime numbers smaller than 'n'
vi segmentedSieve(int n)
{
    // Compute all primes smaller than or equal
    // to square root of n using simple sieve
    int limit = floor(sqrt(n)) + 1;
    vector<int> prime = simpleSieve(limit);
    vi ans(prime);

    // Divide the range [0..n-1] in different segments
    // We have chosen segment size as sqrt(n).
    int low = limit;
    int high = 2 * limit;

    // While all segments of range [0..n-1] are not processed,
    // process one segment at a time
    while (low < n)
    {
        if (high >= n)
            high = n;

        // To mark primes in current range. A value in mark[i]
        // will finally be false if 'i-low' is Not a prime,
        // else true.
        bool mark[limit + 1];
        memset(mark, true, sizeof(mark));

        // Use the found primes by simpleSieve() to find
        // primes in current range
        for (int i = 0; i < prime.size(); i++)
        {
            // Find the minimum number in [low..high] that is
            // a multiple of prime[i] (divisible by prime[i])
            // For example, if low is 31 and prime[i] is 3,
            // we start with 33.
            int loLim = floor(low / prime[i]) * prime[i];
            if (loLim < low)
                loLim += prime[i];

            /* Mark multiples of prime[i] in [low..high]:
                We are marking j - low for j, i.e. each number
                in range [low, high] is mapped to [0, high-low]
                so if range is [50, 100] marking 50 corresponds
                to marking 0, marking 51 corresponds to 1 and
                so on. In this way we need to allocate space only
                for range */
            for (int j = loLim; j < high; j += prime[i])
                mark[j - low] = false;
        }

        // Numbers which are not marked as false are prime
        for (int i = low; i < high; i++)
            if (mark[i - low] == true)
                ans.pb(i);

        // Update low and high for next segment
        low = low + limit;
        high = high + limit;
    }
    return ans;
}

int modInverse(int n, int p)
{
    return power(n, p - 2, p);
}           // Returns n^(-1) mod p

int nCrModPFermat(int n, int r, int p)
{
    // Base case
    if (r == 0)
        return 1;

    // Fill factorial array so that we
    // can find all factorial of r, n
    // and n-r
    int fac[n + 1];
    fac[0] = 1;
    for (int i = 1 ; i <= n; i++)
        fac[i] = fac[i - 1] * i % p;

    return (fac[n] * modInverse(fac[r], p) % p *
            modInverse(fac[n - r], p) % p) % p;
} // Returns nCr % p using Fermat's little theorem

int fact(int n)
{
    if ((n == 0) || (n == 1))
        return 1;
    else
        return n * fact(n - 1);
}

bool isPrime(int num)
{
    bool flag = true;
    for (int i = 2; i <= sqrt(num); i++)
    {
        if (num % i == 0)
        {
            flag = false;
            break;
        }
    }
    return flag;
}

bool isPalindrome(string str)
{
    int i = 0, j = str.size() - 1;
    while (i < j)
    {
        if (str[i] != str[j]) return false;
        i++, j--;
    }
    return true;
}

bool isVowel(char ch)
{
    ch = tolower(ch);
    if (ch == 'a' or ch == 'i' or ch == 'e' or ch == 'o' or ch == 'u') return true;
    return false;
}

bool comp(pii &a, pii &b)
{
    if (a.first > b.first) return true;
    else if (a.first < b.first) return false;

    if (a.second > b.second) return false;
    return true;
}

int seg[400004], ar[100001];
// for segment trees segment array and input array if N = 10^5

// function for segment tree construction
void build_segTree_min_max(int segIndex, int segStart, int segEnd)
{
    if(segStart == segEnd)
    {
        seg[segIndex] = ar[segStart];
        return;
    }

    int mid = (segStart + segEnd) / 2;
    build_segTree_min_max(2 * segIndex, segStart, mid);
    build_segTree_min_max(2 * segIndex + 1, mid + 1, segEnd);

    seg[segIndex] = max(seg[2 * segIndex], seg[2 * segIndex + 1]);
}

// query function for segment tree
int query_segTree(int segIndex, int segStart, int segEnd, int queryStart, int queryEnd)
{
    if(segEnd < queryStart or segStart > queryEnd) return INT_MIN; // out of range

    if(segStart >= queryStart and segEnd <= queryEnd) return seg[segIndex]; //complete in range

    int mid = (segStart + segEnd) / 2;

    return max(query_segTree(2 * segIndex, segStart, mid, queryStart, queryEnd), query_segTree(2 * segIndex + 1, mid + 1, segEnd, queryStart, queryEnd));
}

// update function for segment tree
void update_segTree(int segIndex, int segStart, int segEnd, int queryIndex)
{
    if(segStart == segEnd)                  // reached the leaf node / query index
    {
        seg[segIndex] = ar[queryIndex];
        return;
    }

    int mid = (segStart + segEnd) / 2;
    if(queryIndex <= mid) update_segTree(2 * segIndex, segStart, mid, queryIndex);
    else update_segTree(2 * segIndex + 1, mid + 1, segEnd, queryIndex);

    seg[segIndex] = min(seg[2 * segIndex], seg[2 * segIndex + 1]);
}

// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[].
int getSum(int BITree[], int index)
{
    int sum = 0; // Iniialize result

    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse ancestors of BITree[index]
    while (index > 0)
    {
        // Add current element of BITree to sum
        sum += BITree[index];

        // Move index to parent node in getSum View
        index -= index & (-index);
    }
    return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
    // index in BITree[] is 1 more than the index in arr[]
    index = index + 1;

    // Traverse all ancestors and add 'val'
    while (index <= n)
    {
        // Add 'val' to current node of BI Tree
        BITree[index] += val;

        // Update index to that of parent in update View
        index += index & (-index);
    }
}

// Constructs and returns a Binary Indexed Tree for given
// array of size n.
int *constructBITree(int arr[], int n)
{
    // Create and initialize BITree[] as 0
    int *BITree = new int[n + 1];
    for (int i = 1; i <= n; i++)
        BITree[i] = 0;

    // Store the actual values in BITree[] using update()
    for (int i = 0; i < n; i++)
        updateBIT(BITree, n, i, arr[i]);

    // Uncomment below lines to see contents of BITree[]
    //for (int i=1; i<=n; i++)
    //     cout << BITree[i] << " ";

    return BITree;
}

int min(int a, int b)
{
    if (a < b) return a;
    return b;
}

void test_case()
{
    int n;
    cin >> n;

    fr(i, 1, n + 1){
        int ans = 0;
        fr(x, 1, sqrt(i) + 1)
        {
            fr(y, 1, sqrt(i) + 1)
            {
                int b = x + y;
                int D = 4 * i - 3 * x * x - 3 * y * y - 2 * x * y;
                int rootD = sqrt(D);
                if(rootD * rootD == D and rootD > b)
                {
                    int num = rootD - b;
                    if(num % 2 == 0)
                    {
                        num /= 2;
                        ans++;
                    }
                }
            }
        }
        cout << ans << endl;
    }
}

int32_t main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    t(x)
    {
        test_case();
    }
    return 0;
}

Measured memory_bytes: 3632