// #define NDEBUG //切换release和debug版本

#include <cctype>
#include <iostream>
#include <algorithm>
#include <type_traits>
#include <sstream>

using ull = unsigned long long;

template<class T,size_t size>
struct Array{
    constexpr Array(){};
    constexpr Array(const std::initializer_list<T> list){
        std::copy(list.begin(),list.end(),arr);
    }
    #ifdef NDEBUG
        #define NDB_NOEXCEPT noexcept
        #define NDB_CONSTEXPR constexpr
    #else
        #define NDB_NOEXCEPT
        #define NDB_CONSTEXPR
    #endif
    
    NDB_CONSTEXPR T& operator[](const size_t n)NDB_NOEXCEPT{
        // static_assert(noexcept(Array::operator[](0)), "isn't noexcept");
        #ifndef NDEBUG
            if(n>=size){
                std::ostringstream err_oss;
                err_oss<<"\n[array_size]: "<<size<<"\n[Your index]: "<<n<<'\n';
                throw std::runtime_error(err_oss.str());
            }
        #endif
        return arr[n];
    }
    struct Iterator{
        constexpr Iterator(const size_t n,T *const p)noexcept:now{n},p{p}{}
        bool operator!=(const Iterator &that)const noexcept{
            return this->now!=that.now;
        }
        NDB_CONSTEXPR T& operator*()const NDB_NOEXCEPT{
            #ifndef NDEBUG
                if(now>=size){
                    std::ostringstream err_oss;
                    err_oss<<"[array_size]: "<<size<<" [Your index]: "<<now<<'\n';
                    throw std::runtime_error(err_oss.str());
                }
            #endif
            return p[now];
        }
        constexpr Iterator& operator++()noexcept{
            now++;
            return *this;
        }
        constexpr Iterator& operator--()noexcept{
            now--;
            return *this;
        }
        constexpr Iterator operator--(int)noexcept{
            auto old = *this;
            now--;
            return old;
        }
    private:
        size_t now;
        T *const p;
    };
    constexpr Iterator begin()noexcept{
        return Iterator(0,arr);
    }
    constexpr Iterator end()noexcept{
        return Iterator(size,arr);
    }
private:
    T arr[size];
};


static const size_t max_n {(size_t)2e3+5}; 
ull k, t, n, m;
Array<Array<ull,max_n>,max_n> c,prefix;

static void init(){
    c[0][0] = c[1][0] = c[1][1] = 1;
    for(ull i {2};i<max_n;i++){
        c[i][0]=1;
        for(ull j{1};j<=i;j++){
            c[i][j] = (c[i-1][j-1] + c[i-1][j])%k;
        }
    }
    for(ull i = 2;i<max_n;i++){ //注意这里越界了，这是个bug示例
        for(ull j{1};j<=i;j++){
            prefix[i][j] = prefix[i-1][j]+prefix[i][j-1]-prefix[i-1][j-1] + (c[i][j]==0?1:0);
        }
         prefix[i][i+1] = prefix[i][i];
    }
}

#define NV(v)#v<<" : "<<(v)

template<class T>
struct ReadNumber{
    ReadNumber& operator>>(T &num){
        c=0,w=1,n=0;
        while(!isdigit(c)){
            if constexpr (!std::is_unsigned_v<T>){
                if(c=='-')w=-1;
            }
            c=getchar();
        }
        while(isdigit(c)){
            n=n*10+(c-'0');
            c=getchar();
        }
        num = w*n;
        return *this;
    }
private:
    char c;
    T w,n;
};

ReadNumber<ull> readull;

int main(){
    readull>>t>>k;
    // std::cout<<NV(t)<<'\n'<<NV(k)<<'\n';
    init();
    for(ull i {0};i<t;i++){
        // std::cout<<NV(t)<<'\n'<<NV(k)<<'\n';
        readull>>n>>m;
        // std::cout<<"test\n";
        m = std::min(m,n);
        std::cout<<(prefix[n][m])<<'\n';
    }
}