0w1

HE April Circuits 2A - Bear and All Permutations ( Bigint )

https://www.hackerearth.com/april-circuits/algorithm/2a-bear-and-all-permutations-1/
We can simply simulate for each answer since n is only up to 12. However, it still takes a lot of time, and the number is extremely large, we will have to precompute locally. It takes really a lot of time, but since this is a long duration competition, guess this is it.
UPDATE: Seems that some bugs exist, and a workaround is to set everything into long long.

#include <bits/stdc++.h>
using namespace std;
const int base = 1000000000;
const int base_digits = 9;

struct bigint {
    vector<int> a;
    int sign;

    bigint() :
        sign ( 1 ) {
    }

    bigint ( long long v ) {
        *this = v;
    }

    bigint ( const string &s ) {
        read ( s );
    }

    void operator= ( const bigint &v ) {
        sign = v.sign;
        a = v.a;
    }

    void operator= ( long long v ) {
        sign = 1;
        if ( v < 0 )
            sign = -1, v = -v;
        for ( ; v > 0; v = v / base )
            a.push_back ( v % base );
    }

    bigint operator+ ( const bigint &v ) const {
        if ( sign == v.sign ) {
            bigint res = v;

            for ( int i = 0, carry = 0; i < ( int ) max ( a.size(), v.a.size() ) || carry; ++i ) {
                if ( i == ( int ) res.a.size() )
                    res.a.push_back ( 0 );
                res.a[i] += carry + ( i < ( int ) a.size() ? a[i] : 0 );
                carry = res.a[i] >= base;
                if ( carry )
                    res.a[i] -= base;
            }
            return res;
        }
        return *this - ( -v );
    }

    bigint operator- ( const bigint &v ) const {
        if ( sign == v.sign ) {
            if ( abs() >= v.abs() ) {
                bigint res = *this;
                for ( int i = 0, carry = 0; i < ( int ) v.a.size() || carry; ++i ) {
                    res.a[i] -= carry + ( i < ( int ) v.a.size() ? v.a[i] : 0 );
                    carry = res.a[i] < 0;
                    if ( carry )
                        res.a[i] += base;
                }
                res.trim();
                return res;
            }
            return - ( v - *this );
        }
        return *this + ( -v );
    }

    void operator*= ( int v ) {
        if ( v < 0 )
            sign = -sign, v = -v;
        for ( int i = 0, carry = 0; i < ( int ) a.size() || carry; ++i ) {
            if ( i == ( int ) a.size() )
                a.push_back ( 0 );
            long long cur = a[i] * ( long long ) v + carry;
            carry = ( int ) ( cur / base );
            a[i] = ( int ) ( cur % base );
            //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
        }
        trim();
    }

    bigint operator* ( int v ) const {
        bigint res = *this;
        res *= v;
        return res;
    }

    friend pair<bigint, bigint> divmod ( const bigint &a1, const bigint &b1 ) {
        int norm = base / ( b1.a.back() + 1 );
        bigint a = a1.abs() * norm;
        bigint b = b1.abs() * norm;
        bigint q, r;
        q.a.resize ( a.a.size() );

        for ( int i = a.a.size() - 1; i >= 0; i-- ) {
            r *= base;
            r += a.a[i];
            int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
            int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
            int d = ( ( long long ) base * s1 + s2 ) / b.a.back();
            r -= b * d;
            while ( r < 0 )
                r += b, --d;
            q.a[i] = d;
        }

        q.sign = a1.sign * b1.sign;
        r.sign = a1.sign;
        q.trim();
        r.trim();
        return make_pair ( q, r / norm );
    }

    bigint operator/ ( const bigint &v ) const {
        return divmod ( *this, v ).first;
    }

    bigint operator% ( const bigint &v ) const {
        return divmod ( *this, v ).second;
    }

    void operator/= ( int v ) {
        if ( v < 0 )
            sign = -sign, v = -v;
        for ( int i = ( int ) a.size() - 1, rem = 0; i >= 0; --i ) {
            long long cur = a[i] + rem * ( long long ) base;
            a[i] = ( int ) ( cur / v );
            rem = ( int ) ( cur % v );
        }
        trim();
    }

    bigint operator/ ( int v ) const {
        bigint res = *this;
        res /= v;
        return res;
    }

    int operator% ( int v ) const {
        if ( v < 0 )
            v = -v;
        int m = 0;
        for ( int i = a.size() - 1; i >= 0; --i )
            m = ( a[i] + m * ( long long ) base ) % v;
        return m * sign;
    }

    void operator+= ( const bigint &v ) {
        *this = *this + v;
    }
    void operator-= ( const bigint &v ) {
        *this = *this - v;
    }
    void operator*= ( const bigint &v ) {
        *this = *this * v;
    }
    void operator/= ( const bigint &v ) {
        *this = *this / v;
    }

    bool operator< ( const bigint &v ) const {
        if ( sign != v.sign )
            return sign < v.sign;
        if ( a.size() != v.a.size() )
            return a.size() * sign < v.a.size() * v.sign;
        for ( int i = a.size() - 1; i >= 0; i-- )
            if ( a[i] != v.a[i] )
                return a[i] * sign < v.a[i] * sign;
        return false;
    }

    bool operator> ( const bigint &v ) const {
        return v < *this;
    }
    bool operator<= ( const bigint &v ) const {
        return ! ( v < *this );
    }
    bool operator>= ( const bigint &v ) const {
        return ! ( *this < v );
    }
    bool operator== ( const bigint &v ) const {
        return ! ( *this < v ) && ! ( v < *this );
    }
    bool operator!= ( const bigint &v ) const {
        return *this < v || v < *this;
    }

    void trim() {
        while ( !a.empty() && !a.back() )
            a.pop_back();
        if ( a.empty() )
            sign = 1;
    }

    bool isZero() const {
        return a.empty() || ( a.size() == 1 && !a[0] );
    }

    bigint operator-() const {
        bigint res = *this;
        res.sign = -sign;
        return res;
    }

    bigint abs() const {
        bigint res = *this;
        res.sign *= res.sign;
        return res;
    }

    long long longValue() const {
        long long res = 0;
        for ( int i = a.size() - 1; i >= 0; i-- )
            res = res * base + a[i];
        return res * sign;
    }

    friend bigint gcd ( const bigint &a, const bigint &b ) {
        return b.isZero() ? a : gcd ( b, a % b );
    }
    friend bigint lcm ( const bigint &a, const bigint &b ) {
        return a / gcd ( a, b ) * b;
    }

    void read ( const string &s ) {
        sign = 1;
        a.clear();
        int pos = 0;
        while ( pos < ( int ) s.size() && ( s[pos] == '-' || s[pos] == '+' ) ) {
            if ( s[pos] == '-' )
                sign = -sign;
            ++pos;
        }
        for ( int i = s.size() - 1; i >= pos; i -= base_digits ) {
            int x = 0;
            for ( int j = max ( pos, i - base_digits + 1 ); j <= i; j++ )
                x = x * 10 + s[j] - '0';
            a.push_back ( x );
        }
        trim();
    }

    friend istream& operator>> ( istream &stream, bigint &v ) {
        string s;
        stream >> s;
        v.read ( s );
        return stream;
    }

    friend ostream& operator<< ( ostream &stream, const bigint &v ) {
        if ( v.sign == -1 )
            stream << '-';
        stream << ( v.a.empty() ? 0 : v.a.back() );
        for ( int i = ( int ) v.a.size() - 2; i >= 0; --i )
            stream << setw ( base_digits ) << setfill ( '0' ) << v.a[i];
        return stream;
    }

    static vector<int> convert_base ( const vector<int> &a, int old_digits, int new_digits ) {
        vector<long long> p ( max ( old_digits, new_digits ) + 1 );
        p[0] = 1;
        for ( int i = 1; i < ( int ) p.size(); i++ )
            p[i] = p[i - 1] * 10;
        vector<int> res;
        long long cur = 0;
        int cur_digits = 0;
        for ( int i = 0; i < ( int ) a.size(); i++ ) {
            cur += a[i] * p[cur_digits];
            cur_digits += old_digits;
            while ( cur_digits >= new_digits ) {
                res.push_back ( int ( cur % p[new_digits] ) );
                cur /= p[new_digits];
                cur_digits -= new_digits;
            }
        }
        res.push_back ( ( int ) cur );
        while ( !res.empty() && !res.back() )
            res.pop_back();
        return res;
    }

    typedef vector<long long> vll;

    static vll karatsubaMultiply ( const vll &a, const vll &b ) {
        int n = a.size();
        vll res ( n + n );
        if ( n <= 32 ) {
            for ( int i = 0; i < n; i++ )
                for ( int j = 0; j < n; j++ )
                    res[i + j] += a[i] * b[j];
            return res;
        }

        int k = n >> 1;
        vll a1 ( a.begin(), a.begin() + k );
        vll a2 ( a.begin() + k, a.end() );
        vll b1 ( b.begin(), b.begin() + k );
        vll b2 ( b.begin() + k, b.end() );

        vll a1b1 = karatsubaMultiply ( a1, b1 );
        vll a2b2 = karatsubaMultiply ( a2, b2 );

        for ( int i = 0; i < k; i++ )
            a2[i] += a1[i];
        for ( int i = 0; i < k; i++ )
            b2[i] += b1[i];

        vll r = karatsubaMultiply ( a2, b2 );
        for ( int i = 0; i < ( int ) a1b1.size(); i++ )
            r[i] -= a1b1[i];
        for ( int i = 0; i < ( int ) a2b2.size(); i++ )
            r[i] -= a2b2[i];

        for ( int i = 0; i < ( int ) r.size(); i++ )
            res[i + k] += r[i];
        for ( int i = 0; i < ( int ) a1b1.size(); i++ )
            res[i] += a1b1[i];
        for ( int i = 0; i < ( int ) a2b2.size(); i++ )
            res[i + n] += a2b2[i];
        return res;
    }

    bigint operator* ( const bigint &v ) const {
        vector<int> a6 = convert_base ( this->a, base_digits, 6 );
        vector<int> b6 = convert_base ( v.a, base_digits, 6 );
        vll a ( a6.begin(), a6.end() );
        vll b ( b6.begin(), b6.end() );
        while ( a.size() < b.size() )
            a.push_back ( 0 );
        while ( b.size() < a.size() )
            b.push_back ( 0 );
        while ( a.size() & ( a.size() - 1 ) )
            a.push_back ( 0 ), b.push_back ( 0 );
        vll c = karatsubaMultiply ( a, b );
        bigint res;
        res.sign = sign * v.sign;
        for ( int i = 0, carry = 0; i < ( int ) c.size(); i++ ) {
            long long cur = c[i] + carry;
            res.a.push_back ( ( int ) ( cur % 1000000 ) );
            carry = ( int ) ( cur / 1000000 );
        }
        res.a = convert_base ( res.a, 6, base_digits );
        res.trim();
        return res;
    }
};
/* ----- template for bigint ----- */

typedef long long ll;
const int MOD = 1e9 + 7;

int pre_gcd[ 13 ][ 13 ];
vector< string > precomputed_ans = { "1","1","2","8","68","1504","127792","57140352","258023200384","10151395367145472","3673835865235792306176","13318668301694192513859649536","531680718673514734573555796872790016" };
bigint sol[ 13 ];

void preSolve(){
    for( int i = 1; i <= 12; ++i ){
        sol[ i ] = 0;
        vector< int > vec;
        for( int j = 1; j <= i; ++j )
            vec.push_back( j );
        do{
            bigint prod = 1;
            for( int j = 0; j < i; ++j )
                for( int k = j + 1; k < i; ++k )
                    prod *= pre_gcd[ k - j ][ abs( vec[ k ] - vec[ j ] ) ];
            sol[ i ] += prod;
        } while( next_permutation( vec.begin(), vec.end() ) );
        cout << "sol[ " << i << " ] = " << sol[ i ] << endl;
    }
}

int main(){
    for( int i = 1; i <= 12; ++i )
        sol[ i ] = precomputed_ans[ i ];
    int T; cin >> T;
    while( T-- ){
        int n, m; cin >> n >> m;
        cout << sol[ n ] % m << "\n";
    }
    return 0;
    // precomputed locally
    for( int i = 1; i <= 12; ++i )
        for( int j = 1; j <= 12; ++j )
            pre_gcd[ i ][ j ] = __gcd( i, j );
    preSolve();
    return 0;
}