// package com.company;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.sql.SQLOutput;
import java.util.*;
public class Main {

    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
        //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb1 = new StringBuilder();//int n=Integer.parseInt(s.readLine());
          int t=s.nextInt();
          int k=s.nextInt();int mod=1000000007;
          long [] dp=new long[100001];
          dp[0]=1;long[] p=new long[100001];p[0]=1;
          for(int i=1;i<=100000;i++){
              dp[i]=(p[i-1]+(i+1)/k+dp[i-1]);
               p[i]=(p[i-1]+(i+1)/k);
            //  if(i<=5)  System.out.println(i+" "+dp[i]);
          }
          while(t-->0){
              int l=s.nextInt()-1;int r=s.nextInt()-1;
              long ans=0;
           //   System.out.println(dp[r]+" "+dp[l-1]);
              if(l-1>=0) ans=(dp[r]-dp[l-1])%mod;
              else ans=dp[r]%mod;
          sb1.append(ans+"\n");
          }
        System.out.println(sb1.toString());
    }

    static int ans1=Integer.MAX_VALUE;static int[] vis;
    static   int[] dp;static Queue<Integer>q;
    static void newdfs(int i1,char[][] a,int k,int n,int val){
        while(!q.isEmpty()){
            int i=q.poll();
            vis[i]=1;

            for(int j=i;j<=Math.min(n-1,i+k);j++){
                if(a[i][j]=='1'&&(vis[j]==0)&&dp[i]+1<dp[j]){
                    dp[j]=dp[i]+1;
                    q.add(j);
                }
            }for(int j=i;j>=Math.max(0,i-k);j--){
                if(a[i][j]=='1'&&(vis[j]==0)&&dp[j]+1<dp[i]){
                    dp[j]=dp[i]+1;
                    q.add(j);
                }
            }}
    }
    static  void computeLPSArray(String pat, int M, int lps[])
    {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else // (pat[i] != pat[len])
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else // if (len == 0)
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n)
    {
        // Corner cas
        if (n <= 1) return false;
        if (n <= 3) return true;

        // This is checked so that we can skip
        // middle five numbers in below loop
        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static boolean isPrime(int n, int k)
    {
        // Corner cases
        if (n <= 1 || n == 4) return false;
        if (n <= 3) return true;

        // Try k times
        while (k > 0)
        {
            // Pick a random number in [2..n-2]
            // Above corner cases make sure that n > 4
            int a = 2 + (int)(Math.random() % (n - 4));

            // Fermat's little theorem
            if (power(a, n - 1, n) != 1)
                return false;

            k--;
        }

        return true;
    }
    static double power(double x, long y, int p) {
        double res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    public static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int)gcd((long)numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1=modInverse(denominator / gcd,998244353  );
        //  System.out.println(x1);
        System.out.println((((numerator / gcd )%998244353 *(x1%998244353  ))%998244353  ) );
    }static int max=Integer.MIN_VALUE;
    static int max1=Integer.MIN_VALUE;static int[][] c;static int k=1;static int bhoo=0;
    static int[] car;static int ans;static HashMap<Integer,Integer>[] ha;
    public static void dfs(int ans2,int papa, int i, ArrayList<Integer>[] h, int[] vis,HashMap<Integer,Integer>[] bad) {
        vis[i] = 1;
        if(i!=1&&h[i].size()==1){
            if(ans2!=-1)  {ans++;  sb1.append(ans2+" ");}
        }
        if(h[i]==null) return;
        int hu=0;int hai=0;
        for(Integer j:h[i]){
            if(vis[j]==0&&bad[i].containsKey(j)) {
                hai=1;break;
            }
        }int khi=0;
        for(Integer j:h[i]) {//if(vis[j]==0) flag=1;
            if(vis[j]==0){
                if(!bad[i].containsKey(j)){
                    if(hai==0&&khi==0){khi=1;    dfs(ans2,papa,j,h,vis,bad);}
                    else dfs(-1,papa,j,h,vis,bad);
                }else{
                    if(hu==0){
                        if(papa==0){//ans++;//sb1.append(j+" ");
                            dfs(j,1,j,h,vis,bad);
                        }else{
                            hu=1;
                            dfs( j,1,j,h,vis,bad);}
                    }else{
                        //    ans++;//sb1.append(j+" ");
                        dfs(j,1,j,h,vis,bad);
                    }
                }
            }
        }//if(flag==1) bhoo=-1;
    }static StringBuilder sb1=new StringBuilder();
    public static void bfs(int i, HashMap<Integer, Integer>[] h, int[] vis, int len, int papa) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i);
    }
    static int i(String a) {
        return Integer.parseInt(a);
    }
    static long l(String a) {
        return Long.parseLong(a);
    }
    static String[] inp() throws IOException {
        BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
        return s.readLine().trim().split("\\s+");
    }

    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(int a, int m)
    {

        {
            // If a and m are relatively prime, then modulo inverse
            // is a^(m-2) mode m
            return (power(a, m - 2, m));
        }
    }

    // To compute x^y under modulo m
    static long power(int x, int y, int m)
    {
        if (y == 0)
            return 1;

        long p = power(x, y / 2, m) % m;
        p = (p * p) % m;

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

    // Function to return gcd of a and b

}
class Student
{
    int l;int r;int i;
    public Student(int l, int r,int i) {
        this.l = l;
        this.r = r;this.i=i;
    }
    // Constructor

    // Used to print student details in main()
    public String toString()
    {
        return this.l+" ";
    }
}

class Sortbyroll implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student a, Student b){
        return a.l-b.l;  }
} class Sortbyroll1 implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student a, Student b){
        return a.l-b.l;
    }
}


import java.io.IOException;
import java.util.*;
public class d {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
    //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        //       String[] st=s.readLine().trim().split("\\s+");
        //      a=Integer.parseInt(st[i]);
        //  String[] st1=s.readLine().trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        int mod=1000000007;
        long[] dp=new long[100006];
        dp[0]=1;
        int t=s.nextInt();int k=s.nextInt();
        long [] sum=new long[100006];
        sum[0]=1;
        for(int i=1;i<=100005;i++){
            if(i==1) {
                dp[i]=dp[i-1];sum[1]=1;continue;
            }
            if(i-k>=0){ dp[i]=(dp[i-1]+dp[i-k])%mod;
            sum[i]=(sum[i-1]+dp[i])%mod;
            }
            else {dp[i]=(dp[i-1])%mod;sum[i]=(sum[i-1]+dp[i])%mod;}
           // System.out.println(i+" "+dp[i]);
        }
             while(t-->0){
            int a=s.nextInt();
            int b=s.nextInt();
            if(a==1){
                sb.append(sum[b]%mod+"\n");
            }else
                sb.append((sum[b]%mod-sum[a-1]%mod+mod)%mod+"\n");
             }
        System.out.println(sb.toString());
    }
    static int[] vis;
    public static int countSetBits(int n)
    {
        return (BitsSetTable256[n & 0xff]
                + BitsSetTable256[(n >> 8) & 0xff]
                + BitsSetTable256[(n >> 16) & 0xff]
                + BitsSetTable256[n >> 24]);
    }
    static int[] BitsSetTable256 ;
    public static void initialize(int n)
    {
        BitsSetTable256[0] = 0;
        for (int i = 0; i <=Math.pow(2,n); i++) {
            BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
        }
    }
    static HashMap<Integer,Integer>[] val;//static int[] vis;static int y;
    static boolean dfs(int x ,int i,ArrayList<Integer>[] adj){
      vis[i]=1;
     // if(x==1) System.out.print(i+" ");
      if(adj[i]==null) return false;
      for(int j:adj[i]){
        //  if(x==1) System.out.print(j+" ");
          if(j==x) return true;
          if(vis[j]==0) return dfs(x,j,adj);
      }return false;
    }

    static  void computeLPSArray(String pat, int M, int lps[]) {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;

        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static long powerwithmod(long  x, long y, int p) {
        long  res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static long  powerwithoutmod(long x, int y) {
        long  temp;
        if( y == 0)
            return 1;
        temp = powerwithoutmod(x, y/2);
        if (y%2 == 0)
            return temp*temp;
        else
        {
            if(y > 0)
                return x * temp * temp;
            else
                return (temp * temp) / x;
        }
    }
    static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int) gcd((long) numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1 = modInverse(denominator / gcd, 998244353);
        //  System.out.println(x1);
        System.out.println((((numerator / gcd) % 998244353 * (x1 % 998244353)) % 998244353));
    }
    static int bfs(int i1, ArrayList<Integer>[] h, int[] vis, int n,int val1) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i1);Queue<Integer> aq=new LinkedList<Integer>();
        aq.add(0);
        while(!q.isEmpty()){
            int i=q.poll();
            int val=aq.poll();
            if(i==n){
                return val;
            }
            if(h[i]!=null){
                for(Integer j:h[i]){
                    if(vis[j]==0){
                        q.add(j);vis[j]=1;
                        aq.add(val+1);}
                }
            }
        }return -1;
    }
    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(long a, int m)
    {
        return (powerwithmod(a, m - 2, m));
    }
    static int MAXN;
    static int[] spf=new int[MAXN];
    static void sieve() {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (int i=3; i*i<MAXN; i++)
        {
            if (spf[i] == i)
            {
                for (int j=i*i; j<MAXN; j+=i)

                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }
    static ArrayList<Integer> getFactorizationUsingSeive(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
   static long[] fac ;
     static void calculatefac(int mod){
         fac[0]=1;
        for (int i = 1 ;i <= MAXN; i++)
            fac[i] = fac[i-1] * i % mod;
     }
      static long nCrModPFermat(int n, int r, int mod) {
         if (r == 0)
            return 1;
        fac[0] = 1;
        return (fac[n]* modInverse(fac[r], mod)
                % mod * modInverse(fac[n-r], mod)
                                    % mod) % mod;
    } }
class Student {
    long  l;long r;int x;
    public Student(long l, long r) {
        this.l = l;
        this.r = r;this.x=x;
    }

    public String toString()
    {
        return this.l+" ";
    }
}
class Sortbyroll implements Comparator<Student>
{

    public int compare(Student a, Student b){
      if(a.l<b.l) return 1;
      else if(a.l==b.l){
          if(a.r==b.r){
              return 0;
          }
          if(a.r<b.r) return -1;
          return 1;}
      return -1;  }
}


import java.io.IOException;
import java.util.*;
public class d {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
    //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        //       String[] st=s.readLine().trim().split("\\s+");
        //      a=Integer.parseInt(st[i]);
        //  String[] st1=s.readLine().trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        int mod=1000000007;
        long[] dp=new long[100006];
        dp[0]=1;
        int t=s.nextInt();int k=s.nextInt();
        long [] sum=new long[100006];
        sum[0]=1;
        for(int i=1;i<=100005;i++){
            if(i==1) {
                dp[i]=dp[i-1];sum[1]=1;continue;
            }
            if(i-k>=0){ dp[i]=(dp[i-1]+dp[i-k])%mod;
            sum[i]=(sum[i-1]+dp[i])%mod;
            }
            else {dp[i]=(dp[i-1])%mod;sum[i]=(sum[i-1]+dp[i])%mod;}
           // System.out.println(i+" "+dp[i]);
        }
             while(t-->0){
            int a=s.nextInt();
            int b=s.nextInt();
            if(a==1){
                sb.append(sum[b]+"\n");
            }else
                sb.append((sum[b]-sum[a-1])+"\n");
             }
        System.out.println(sb.toString());
    }
    static int[] vis;
    public static int countSetBits(int n)
    {
        return (BitsSetTable256[n & 0xff]
                + BitsSetTable256[(n >> 8) & 0xff]
                + BitsSetTable256[(n >> 16) & 0xff]
                + BitsSetTable256[n >> 24]);
    }
    static int[] BitsSetTable256 ;
    public static void initialize(int n)
    {
        BitsSetTable256[0] = 0;
        for (int i = 0; i <=Math.pow(2,n); i++) {
            BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
        }
    }
    static HashMap<Integer,Integer>[] val;//static int[] vis;static int y;
    static boolean dfs(int x ,int i,ArrayList<Integer>[] adj){
      vis[i]=1;
     // if(x==1) System.out.print(i+" ");
      if(adj[i]==null) return false;
      for(int j:adj[i]){
        //  if(x==1) System.out.print(j+" ");
          if(j==x) return true;
          if(vis[j]==0) return dfs(x,j,adj);
      }return false;
    }

    static  void computeLPSArray(String pat, int M, int lps[]) {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;

        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static long powerwithmod(long  x, long y, int p) {
        long  res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static long  powerwithoutmod(long x, int y) {
        long  temp;
        if( y == 0)
            return 1;
        temp = powerwithoutmod(x, y/2);
        if (y%2 == 0)
            return temp*temp;
        else
        {
            if(y > 0)
                return x * temp * temp;
            else
                return (temp * temp) / x;
        }
    }
    static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int) gcd((long) numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1 = modInverse(denominator / gcd, 998244353);
        //  System.out.println(x1);
        System.out.println((((numerator / gcd) % 998244353 * (x1 % 998244353)) % 998244353));
    }
    static int bfs(int i1, ArrayList<Integer>[] h, int[] vis, int n,int val1) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i1);Queue<Integer> aq=new LinkedList<Integer>();
        aq.add(0);
        while(!q.isEmpty()){
            int i=q.poll();
            int val=aq.poll();
            if(i==n){
                return val;
            }
            if(h[i]!=null){
                for(Integer j:h[i]){
                    if(vis[j]==0){
                        q.add(j);vis[j]=1;
                        aq.add(val+1);}
                }
            }
        }return -1;
    }
    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(long a, int m)
    {
        return (powerwithmod(a, m - 2, m));
    }
    static int MAXN;
    static int[] spf=new int[MAXN];
    static void sieve() {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (int i=3; i*i<MAXN; i++)
        {
            if (spf[i] == i)
            {
                for (int j=i*i; j<MAXN; j+=i)

                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }
    static ArrayList<Integer> getFactorizationUsingSeive(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
   static long[] fac ;
     static void calculatefac(int mod){
         fac[0]=1;
        for (int i = 1 ;i <= MAXN; i++)
            fac[i] = fac[i-1] * i % mod;
     }
      static long nCrModPFermat(int n, int r, int mod) {
         if (r == 0)
            return 1;
        fac[0] = 1;
        return (fac[n]* modInverse(fac[r], mod)
                % mod * modInverse(fac[n-r], mod)
                                    % mod) % mod;
    } }
class Student {
    long  l;long r;int x;
    public Student(long l, long r) {
        this.l = l;
        this.r = r;this.x=x;
    }

    public String toString()
    {
        return this.l+" ";
    }
}
class Sortbyroll implements Comparator<Student>
{

    public int compare(Student a, Student b){
      if(a.l<b.l) return 1;
      else if(a.l==b.l){
          if(a.r==b.r){
              return 0;
          }
          if(a.r<b.r) return -1;
          return 1;}
      return -1;  }
}


// package com.company;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.sql.SQLOutput;
import java.util.*;
public class Main {

    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
        //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb1 = new StringBuilder();//int n=Integer.parseInt(s.readLine());
          int t=s.nextInt();
          int k=s.nextInt();int mod=1000000007;
          long [] dp=new long[100001];
          dp[0]=1;long[] p=new long[100001];p[0]=1;
          for(int i=1;i<=100000;i++){
              dp[i]=(p[i-1]+(i+1)/k+dp[i-1])%mod;
               p[i]=(p[i-1]+(i+1)/k)%mod;
            //  if(i<=5)  System.out.println(i+" "+dp[i]);
          }
          while(t-->0){
              int l=s.nextInt()-1;int r=s.nextInt()-1;
              long ans=0;
              if(l-1>=0) ans=(dp[r]-dp[l-1])%mod;
              else ans=dp[r]%mod;
          sb1.append(ans+"\n");
          }
        System.out.println(sb1.toString());
    }

    static int ans1=Integer.MAX_VALUE;static int[] vis;
    static   int[] dp;static Queue<Integer>q;
    static void newdfs(int i1,char[][] a,int k,int n,int val){
        while(!q.isEmpty()){
            int i=q.poll();
            vis[i]=1;

            for(int j=i;j<=Math.min(n-1,i+k);j++){
                if(a[i][j]=='1'&&(vis[j]==0)&&dp[i]+1<dp[j]){
                    dp[j]=dp[i]+1;
                    q.add(j);
                }
            }for(int j=i;j>=Math.max(0,i-k);j--){
                if(a[i][j]=='1'&&(vis[j]==0)&&dp[j]+1<dp[i]){
                    dp[j]=dp[i]+1;
                    q.add(j);
                }
            }}
    }
    static  void computeLPSArray(String pat, int M, int lps[])
    {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else // (pat[i] != pat[len])
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else // if (len == 0)
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n)
    {
        // Corner cas
        if (n <= 1) return false;
        if (n <= 3) return true;

        // This is checked so that we can skip
        // middle five numbers in below loop
        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static boolean isPrime(int n, int k)
    {
        // Corner cases
        if (n <= 1 || n == 4) return false;
        if (n <= 3) return true;

        // Try k times
        while (k > 0)
        {
            // Pick a random number in [2..n-2]
            // Above corner cases make sure that n > 4
            int a = 2 + (int)(Math.random() % (n - 4));

            // Fermat's little theorem
            if (power(a, n - 1, n) != 1)
                return false;

            k--;
        }

        return true;
    }
    static double power(double x, long y, int p) {
        double res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    public static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int)gcd((long)numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1=modInverse(denominator / gcd,998244353  );
        //  System.out.println(x1);
        System.out.println((((numerator / gcd )%998244353 *(x1%998244353  ))%998244353  ) );
    }static int max=Integer.MIN_VALUE;
    static int max1=Integer.MIN_VALUE;static int[][] c;static int k=1;static int bhoo=0;
    static int[] car;static int ans;static HashMap<Integer,Integer>[] ha;
    public static void dfs(int ans2,int papa, int i, ArrayList<Integer>[] h, int[] vis,HashMap<Integer,Integer>[] bad) {
        vis[i] = 1;
        if(i!=1&&h[i].size()==1){
            if(ans2!=-1)  {ans++;  sb1.append(ans2+" ");}
        }
        if(h[i]==null) return;
        int hu=0;int hai=0;
        for(Integer j:h[i]){
            if(vis[j]==0&&bad[i].containsKey(j)) {
                hai=1;break;
            }
        }int khi=0;
        for(Integer j:h[i]) {//if(vis[j]==0) flag=1;
            if(vis[j]==0){
                if(!bad[i].containsKey(j)){
                    if(hai==0&&khi==0){khi=1;    dfs(ans2,papa,j,h,vis,bad);}
                    else dfs(-1,papa,j,h,vis,bad);
                }else{
                    if(hu==0){
                        if(papa==0){//ans++;//sb1.append(j+" ");
                            dfs(j,1,j,h,vis,bad);
                        }else{
                            hu=1;
                            dfs( j,1,j,h,vis,bad);}
                    }else{
                        //    ans++;//sb1.append(j+" ");
                        dfs(j,1,j,h,vis,bad);
                    }
                }
            }
        }//if(flag==1) bhoo=-1;
    }static StringBuilder sb1=new StringBuilder();
    public static void bfs(int i, HashMap<Integer, Integer>[] h, int[] vis, int len, int papa) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i);
    }
    static int i(String a) {
        return Integer.parseInt(a);
    }
    static long l(String a) {
        return Long.parseLong(a);
    }
    static String[] inp() throws IOException {
        BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
        return s.readLine().trim().split("\\s+");
    }

    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(int a, int m)
    {

        {
            // If a and m are relatively prime, then modulo inverse
            // is a^(m-2) mode m
            return (power(a, m - 2, m));
        }
    }

    // To compute x^y under modulo m
    static long power(int x, int y, int m)
    {
        if (y == 0)
            return 1;

        long p = power(x, y / 2, m) % m;
        p = (p * p) % m;

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

    // Function to return gcd of a and b

}
class Student
{
    int l;int r;int i;
    public Student(int l, int r,int i) {
        this.l = l;
        this.r = r;this.i=i;
    }
    // Constructor

    // Used to print student details in main()
    public String toString()
    {
        return this.l+" ";
    }
}

class Sortbyroll implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student a, Student b){
        return a.l-b.l;  }
} class Sortbyroll1 implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student a, Student b){
        return a.l-b.l;
    }
}


import java.io.IOException;
import java.util.*;
public class d {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
    //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        //       String[] st=s.readLine().trim().split("\\s+");
        //      a=Integer.parseInt(st[i]);
        //  String[] st1=s.readLine().trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        int mod=1000000007;
        long[] dp=new long[100006];
        dp[0]=1;
        int t=s.nextInt();int k=s.nextInt();
        long [] sum=new long[100006];
        sum[0]=1;
        for(int i=1;i<=100005;i++){
            if(i==1) {
                dp[i]=dp[i-1];sum[1]=1;continue;
            }
            if(i-k>=0&&k!=1){ dp[i]=(dp[i-1]+dp[i-k])%mod;
            sum[i]=(sum[i-1]+dp[i])%mod;
            }
            else {dp[i]=(dp[i-1])%mod;sum[i]=(sum[i-1]+dp[i])%mod;}
           // System.out.println(i+" "+dp[i]);
        }
             while(t-->0){
            int a=s.nextInt();
            int b=s.nextInt();
            if(a==1){
                sb.append(sum[b]%mod+"\n");
            }else
                sb.append((sum[b]%mod-sum[a-1]%mod+mod)%mod+"\n");
             }
        System.out.println(sb.toString());
    }
    static int[] vis;
    public static int countSetBits(int n)
    {
        return (BitsSetTable256[n & 0xff]
                + BitsSetTable256[(n >> 8) & 0xff]
                + BitsSetTable256[(n >> 16) & 0xff]
                + BitsSetTable256[n >> 24]);
    }
    static int[] BitsSetTable256 ;
    public static void initialize(int n)
    {
        BitsSetTable256[0] = 0;
        for (int i = 0; i <=Math.pow(2,n); i++) {
            BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
        }
    }
    static HashMap<Integer,Integer>[] val;//static int[] vis;static int y;
    static boolean dfs(int x ,int i,ArrayList<Integer>[] adj){
      vis[i]=1;
     // if(x==1) System.out.print(i+" ");
      if(adj[i]==null) return false;
      for(int j:adj[i]){
        //  if(x==1) System.out.print(j+" ");
          if(j==x) return true;
          if(vis[j]==0) return dfs(x,j,adj);
      }return false;
    }

    static  void computeLPSArray(String pat, int M, int lps[]) {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;

        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static long powerwithmod(long  x, long y, int p) {
        long  res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static long  powerwithoutmod(long x, int y) {
        long  temp;
        if( y == 0)
            return 1;
        temp = powerwithoutmod(x, y/2);
        if (y%2 == 0)
            return temp*temp;
        else
        {
            if(y > 0)
                return x * temp * temp;
            else
                return (temp * temp) / x;
        }
    }
    static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int) gcd((long) numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1 = modInverse(denominator / gcd, 998244353);
        //  System.out.println(x1);
        System.out.println((((numerator / gcd) % 998244353 * (x1 % 998244353)) % 998244353));
    }
    static int bfs(int i1, ArrayList<Integer>[] h, int[] vis, int n,int val1) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i1);Queue<Integer> aq=new LinkedList<Integer>();
        aq.add(0);
        while(!q.isEmpty()){
            int i=q.poll();
            int val=aq.poll();
            if(i==n){
                return val;
            }
            if(h[i]!=null){
                for(Integer j:h[i]){
                    if(vis[j]==0){
                        q.add(j);vis[j]=1;
                        aq.add(val+1);}
                }
            }
        }return -1;
    }
    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(long a, int m)
    {
        return (powerwithmod(a, m - 2, m));
    }
    static int MAXN;
    static int[] spf=new int[MAXN];
    static void sieve() {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (int i=3; i*i<MAXN; i++)
        {
            if (spf[i] == i)
            {
                for (int j=i*i; j<MAXN; j+=i)

                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }
    static ArrayList<Integer> getFactorizationUsingSeive(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
   static long[] fac ;
     static void calculatefac(int mod){
         fac[0]=1;
        for (int i = 1 ;i <= MAXN; i++)
            fac[i] = fac[i-1] * i % mod;
     }
      static long nCrModPFermat(int n, int r, int mod) {
         if (r == 0)
            return 1;
        fac[0] = 1;
        return (fac[n]* modInverse(fac[r], mod)
                % mod * modInverse(fac[n-r], mod)
                                    % mod) % mod;
    } }
class Student {
    long  l;long r;int x;
    public Student(long l, long r) {
        this.l = l;
        this.r = r;this.x=x;
    }

    public String toString()
    {
        return this.l+" ";
    }
}
class Sortbyroll implements Comparator<Student>
{

    public int compare(Student a, Student b){
      if(a.l<b.l) return 1;
      else if(a.l==b.l){
          if(a.r==b.r){
              return 0;
          }
          if(a.r<b.r) return -1;
          return 1;}
      return -1;  }
}


import java.io.IOException;
import java.util.*;
public class d {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
    //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        //       String[] st=s.readLine().trim().split("\\s+");
        //      a=Integer.parseInt(st[i]);
        //  String[] st1=s.readLine().trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        int mod=1000000007;
        long[] dp=new long[100006];
        dp[0]=1;
        int t=s.nextInt();int k=s.nextInt();
        long [] sum=new long[100006];
        sum[0]=1;
        for(int i=1;i<=100005;i++){
            if(i==1) {
                dp[i]=dp[i-1];sum[1]=1;continue;
            }
            if(i-k>=0){ dp[i]=(dp[i-1]+dp[i-k]);
            sum[i]=(sum[i-1]+dp[i])%mod;
            }
            else {dp[i]=(dp[i-1]);sum[i]=(sum[i-1]+dp[i])%mod;}
           // System.out.println(i+" "+dp[i]);
        }
             while(t-->0){
            int a=s.nextInt();
            int b=s.nextInt();
            if(a==1){
                sb.append(sum[b]+"\n");
            }else
                sb.append((sum[b]-sum[a-1])+"\n");
             }
        System.out.println(sb.toString());
    }
    static int[] vis;
    public static int countSetBits(int n)
    {
        return (BitsSetTable256[n & 0xff]
                + BitsSetTable256[(n >> 8) & 0xff]
                + BitsSetTable256[(n >> 16) & 0xff]
                + BitsSetTable256[n >> 24]);
    }
    static int[] BitsSetTable256 ;
    public static void initialize(int n)
    {
        BitsSetTable256[0] = 0;
        for (int i = 0; i <=Math.pow(2,n); i++) {
            BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
        }
    }
    static HashMap<Integer,Integer>[] val;//static int[] vis;static int y;
    static boolean dfs(int x ,int i,ArrayList<Integer>[] adj){
      vis[i]=1;
     // if(x==1) System.out.print(i+" ");
      if(adj[i]==null) return false;
      for(int j:adj[i]){
        //  if(x==1) System.out.print(j+" ");
          if(j==x) return true;
          if(vis[j]==0) return dfs(x,j,adj);
      }return false;
    }

    static  void computeLPSArray(String pat, int M, int lps[]) {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;

        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static long powerwithmod(long  x, long y, int p) {
        long  res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static long  powerwithoutmod(long x, int y) {
        long  temp;
        if( y == 0)
            return 1;
        temp = powerwithoutmod(x, y/2);
        if (y%2 == 0)
            return temp*temp;
        else
        {
            if(y > 0)
                return x * temp * temp;
            else
                return (temp * temp) / x;
        }
    }
    static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int) gcd((long) numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1 = modInverse(denominator / gcd, 998244353);
        //  System.out.println(x1);
        System.out.println((((numerator / gcd) % 998244353 * (x1 % 998244353)) % 998244353));
    }
    static int bfs(int i1, ArrayList<Integer>[] h, int[] vis, int n,int val1) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i1);Queue<Integer> aq=new LinkedList<Integer>();
        aq.add(0);
        while(!q.isEmpty()){
            int i=q.poll();
            int val=aq.poll();
            if(i==n){
                return val;
            }
            if(h[i]!=null){
                for(Integer j:h[i]){
                    if(vis[j]==0){
                        q.add(j);vis[j]=1;
                        aq.add(val+1);}
                }
            }
        }return -1;
    }
    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(long a, int m)
    {
        return (powerwithmod(a, m - 2, m));
    }
    static int MAXN;
    static int[] spf=new int[MAXN];
    static void sieve() {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (int i=3; i*i<MAXN; i++)
        {
            if (spf[i] == i)
            {
                for (int j=i*i; j<MAXN; j+=i)

                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }
    static ArrayList<Integer> getFactorizationUsingSeive(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
   static long[] fac ;
     static void calculatefac(int mod){
         fac[0]=1;
        for (int i = 1 ;i <= MAXN; i++)
            fac[i] = fac[i-1] * i % mod;
     }
      static long nCrModPFermat(int n, int r, int mod) {
         if (r == 0)
            return 1;
        fac[0] = 1;
        return (fac[n]* modInverse(fac[r], mod)
                % mod * modInverse(fac[n-r], mod)
                                    % mod) % mod;
    } }
class Student {
    long  l;long r;int x;
    public Student(long l, long r) {
        this.l = l;
        this.r = r;this.x=x;
    }

    public String toString()
    {
        return this.l+" ";
    }
}
class Sortbyroll implements Comparator<Student>
{

    public int compare(Student a, Student b){
      if(a.l<b.l) return 1;
      else if(a.l==b.l){
          if(a.r==b.r){
              return 0;
          }
          if(a.r<b.r) return -1;
          return 1;}
      return -1;  }
}


import java.io.IOException;
import java.util.*;
public class d {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
    //BufferedReader s=new BufferedReader(new InputStreamReader(System.in));
        //       String[] st=s.readLine().trim().split("\\s+");
        //      a=Integer.parseInt(st[i]);
        //  String[] st1=s.readLine().trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();
        int mod=1000000007;
        long[] dp=new long[100006];
        dp[0]=1;
        int t=s.nextInt();int k=s.nextInt();
        long [] sum=new long[100006];
        sum[0]=1;
        for(int i=1;i<=100005;i++){
            if(i==1) {
                dp[i]=dp[i-1];sum[1]=1;
                if(k==1) {
                    dp[i]++;sum[i]++;
                }
                continue;
            }
            if(i-k>=0){ dp[i]=(dp[i-1]+dp[i-k])%mod;
            sum[i]=(sum[i-1]+dp[i])%mod;
            }
            else {dp[i]=(dp[i-1])%mod;sum[i]=(sum[i-1]+dp[i])%mod;}
           // System.out.println(i+" "+dp[i]);
        }
             while(t-->0){
            int a=s.nextInt();
            int b=s.nextInt();
            if(a==1){
                sb.append(sum[b]%mod+"\n");
            }else
                sb.append((sum[b]%mod-sum[a-1]%mod+mod)%mod+"\n");
             }
        System.out.println(sb.toString());
    }
    static int[] vis;
    public static int countSetBits(int n)
    {
        return (BitsSetTable256[n & 0xff]
                + BitsSetTable256[(n >> 8) & 0xff]
                + BitsSetTable256[(n >> 16) & 0xff]
                + BitsSetTable256[n >> 24]);
    }
    static int[] BitsSetTable256 ;
    public static void initialize(int n)
    {
        BitsSetTable256[0] = 0;
        for (int i = 0; i <=Math.pow(2,n); i++) {
            BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
        }
    }
    static HashMap<Integer,Integer>[] val;//static int[] vis;static int y;
    static boolean dfs(int x ,int i,ArrayList<Integer>[] adj){
      vis[i]=1;
     // if(x==1) System.out.print(i+" ");
      if(adj[i]==null) return false;
      for(int j:adj[i]){
        //  if(x==1) System.out.print(j+" ");
          if(j==x) return true;
          if(vis[j]==0) return dfs(x,j,adj);
      }return false;
    }

    static  void computeLPSArray(String pat, int M, int lps[]) {
        int len = 0;
        int i = 1;
        lps[0] = 0;
        while (i < M) {
            if (pat.charAt(i) == pat.charAt(len)) {
                len++;
                lps[i] = len;
                i++;
            }
            else
            {
                if (len != 0) {
                    len = lps[len - 1];
                }
                else
                {
                    lps[i] = len;
                    i++;
                }
            }
        }
    }
    static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;

        if (n % 2 == 0 || n % 3 == 0) return false;

        for (int i = 5; i * i <= n; i = i + 6)
            if (n % i == 0 || n % (i + 2) == 0)
                return false;

        return true;
    }
    static long powerwithmod(long  x, long y, int p) {
        long  res = 1;
        x = x % p;
        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static long  powerwithoutmod(long x, int y) {
        long  temp;
        if( y == 0)
            return 1;
        temp = powerwithoutmod(x, y/2);
        if (y%2 == 0)
            return temp*temp;
        else
        {
            if(y > 0)
                return x * temp * temp;
            else
                return (temp * temp) / x;
        }
    }
    static void fracion(double x) {
        String a = "" + x;
        String spilts[] = a.split("\\."); // split using decimal
        int b = spilts[1].length(); // find the decimal length
        int denominator = (int) Math.pow(10, b); // calculate the denominator
        int numerator = (int) (x * denominator); // calculate the nerumrator Ex
        // 1.2*10 = 12
        int gcd = (int) gcd((long) numerator, denominator); // Find the greatest common
        // divisor bw them
        String fraction = "" + numerator / gcd + "/" + denominator / gcd;
        // System.out.println((denominator/gcd));
        long x1 = modInverse(denominator / gcd, 998244353);
        //  System.out.println(x1);
        System.out.println((((numerator / gcd) % 998244353 * (x1 % 998244353)) % 998244353));
    }
    static int bfs(int i1, ArrayList<Integer>[] h, int[] vis, int n,int val1) {
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(i1);Queue<Integer> aq=new LinkedList<Integer>();
        aq.add(0);
        while(!q.isEmpty()){
            int i=q.poll();
            int val=aq.poll();
            if(i==n){
                return val;
            }
            if(h[i]!=null){
                for(Integer j:h[i]){
                    if(vis[j]==0){
                        q.add(j);vis[j]=1;
                        aq.add(val+1);}
                }
            }
        }return -1;
    }
    static long gcd(long a, long b) {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }
    static long modInverse(long a, int m)
    {
        return (powerwithmod(a, m - 2, m));
    }
    static int MAXN;
    static int[] spf=new int[MAXN];
    static void sieve() {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (int i=3; i*i<MAXN; i++)
        {
            if (spf[i] == i)
            {
                for (int j=i*i; j<MAXN; j+=i)

                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }
    static ArrayList<Integer> getFactorizationUsingSeive(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        return ret;
    }
   static long[] fac ;
     static void calculatefac(int mod){
         fac[0]=1;
        for (int i = 1 ;i <= MAXN; i++)
            fac[i] = fac[i-1] * i % mod;
     }
      static long nCrModPFermat(int n, int r, int mod) {
         if (r == 0)
            return 1;
        fac[0] = 1;
        return (fac[n]* modInverse(fac[r], mod)
                % mod * modInverse(fac[n-r], mod)
                                    % mod) % mod;
    } }
class Student {
    long  l;long r;int x;
    public Student(long l, long r) {
        this.l = l;
        this.r = r;this.x=x;
    }

    public String toString()
    {
        return this.l+" ";
    }
}
class Sortbyroll implements Comparator<Student>
{

    public int compare(Student a, Student b){
      if(a.l<b.l) return 1;
      else if(a.l==b.l){
          if(a.r==b.r){
              return 0;
          }
          if(a.r<b.r) return -1;
          return 1;}
      return -1;  }
}


import java.util.Scanner;

public class flowers {
	static int dp[];

	static void fill(int n, int k) {
		dp = new int[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = dp[i - 1] + ((i - k >= 0) ? dp[i - k] : 0);
		for (int i = 1; i < n + 1; i++)
			dp[i] += dp[i - 1];
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1]) + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.Scanner;

public class flowers {
	static long dp[];
	static int mod = 1000000007;

	static void fill(int n, int k) {
		dp = new long[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = (dp[i - 1] + ((i - k >= 0) ? dp[i - k] : 0)) % mod;
		for (int i = 1; i < n + 1; i++)
			dp[i] = (dp[i] + dp[i - 1]) % 1000000007;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1]) + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.Scanner;

public class flowers {
	static long dp[];
	static int mod = 1000000007;

	static void fill(int n, int k) {
		dp = new long[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = (dp[i - 1] + ((i - k >= 0) ? dp[i - k] : 0)) % mod;
		for (int i = 1; i < n + 1; i++) {
			dp[i] = (dp[i] + dp[i - 1]) % mod;
			if (dp[i] < 0) {
				System.out.println(i + " " + dp[i]);
				break;
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1] + mod) % mod + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.Scanner;

public class flowers {
	static long dp[];
	static int mod = 1000000007;

	static void fill(int n, int k) {
		dp = new long[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = ((dp[i - 1] % mod) + (((i - k >= 0) ? dp[i - k] : 0) % mod)) % mod;
		for (int i = 1; i < n + 1; i++) {
			dp[i] = ((dp[i] % mod) + (dp[i - 1] % mod)) % mod;
			if (dp[i] < 0) {
				System.out.println(i + " " + dp[i]);
				break;
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1] + mod) % mod + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.Scanner;

public class flowers {
	static long dp[];
	static int mod = 1000000007;

	static void fill(int n, int k) {
		dp = new long[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = ((dp[i - 1] % mod) + (((i - k >= 0) ? dp[i - k] : 0) % mod)) % mod;
		for (int i = 1; i < n + 1; i++)
			dp[i] = ((dp[i] % mod) + (dp[i - 1] % mod)) % mod;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1]) + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.Scanner;

public class flowers {
	static long dp[];
	static int mod = 1000000007;

	static void fill(int n, int k) {
		dp = new long[n + 1];
		dp[0] = 1;
		for (int i = 1; i < n + 1; i++)
			dp[i] = (dp[i - 1] % mod) + (((i - k >= 0) ? dp[i - k] : 0) % mod);
		for (int i = 1; i < n + 1; i++)
			dp[i] = (dp[i] % mod) + (dp[i - 1] % mod);
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		StringBuilder ans = new StringBuilder();
		int t = sc.nextInt(), k = sc.nextInt();
		fill(100000, k);
		while (--t >= 0) {
			int a = sc.nextInt(), b = sc.nextInt();
			ans.append((dp[b] - dp[a - 1]) + "\n");
		}
		sc.close();
		System.out.print(ans);
	}
}


import java.util.*;
import java.io.*;
public class Main{
    static class InputReader {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int snext() {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars) {
                curChar = 0;
                try {
                    snumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n) {
            int a[] = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = nextInt();
            }
            return a;
        }

        public String readString() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }

    }
    static class OutputWriter {
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream) {
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
		}

		public OutputWriter(Writer writer) {
			this.writer = new PrintWriter(writer);
		}

		public void print(Object...objects) {
			for (int i = 0; i < objects.length; i++) {
				if (i != 0)
					writer.print(' ');
				writer.print(objects[i]);
			}
		}

		public void printLine(Object...objects) {
			print(objects);
			writer.println();
		}

		public void close() {
			writer.close();
		}

		public void flush() {
			writer.flush();
		}

		}

    static class IOUtils {

		public static int[] readIntArray(InputReader in, int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++)
                array[i] = in.nextInt();
            return array;
        }

    }
    static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
    static int mod = (int)(1e9+7);
    public static long pow(long a,long b)
    {
        long ans = 1;
        while(b> 0)
        {
            if((b & 1)==1){
                ans = (ans*a) % mod;
            }
            a = (a*a) % mod;
            b = b>>1;
        }
        return ans;
    }

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        OutputWriter out = new OutputWriter(System.out);
        //IOUtils io = new IOUtils();
        int t = in.nextInt(),k = in.nextInt();
        long[] dp = new long[100001];
        for(int i=0;i<dp.length;i++)
        {
            if(i<k)
            {
                dp[i] = 1;
            }
            else{
                dp[i] = (dp[i-1]+dp[i-k])%mod;
            }
        }
        for(int i=1;i<dp.length;i++)
        {
            dp[i]=(dp[i]+dp[i-1])%mod;
        }
        for(int x=0;x<t;x++)
        {
            int a = in.nextInt();
            int b = in.nextInt();
            long res = (dp[b] - dp[a-1])%mod;
            out.printLine(res);
        }
        out.flush();
        out.close();
    }
}


import java.util.*;
import java.io.*;
public class Main{
    static class InputReader {

        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int snext() {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars) {
                curChar = 0;
                try {
                    snumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n) {
            int a[] = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = nextInt();
            }
            return a;
        }

        public String readString() {
            int c = snext();
            while (isSpaceChar(c)) {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }

    }
    static class OutputWriter {
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream) {
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
		}

		public OutputWriter(Writer writer) {
			this.writer = new PrintWriter(writer);
		}

		public void print(Object...objects) {
			for (int i = 0; i < objects.length; i++) {
				if (i != 0)
					writer.print(' ');
				writer.print(objects[i]);
			}
		}

		public void printLine(Object...objects) {
			print(objects);
			writer.println();
		}

		public void close() {
			writer.close();
		}

		public void flush() {
			writer.flush();
		}

		}

    static class IOUtils {

		public static int[] readIntArray(InputReader in, int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++)
                array[i] = in.nextInt();
            return array;
        }

    }
    static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
    static int mod = (int)(1e9+7);
    public static long pow(long a,long b)
    {
        long ans = 1;
        while(b> 0)
        {
            if((b & 1)==1){
                ans = (ans*a) % mod;
            }
            a = (a*a) % mod;
            b = b>>1;
        }
        return ans;
    }

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        OutputWriter out = new OutputWriter(System.out);
        //IOUtils io = new IOUtils();
        int t = in.nextInt(),k = in.nextInt();
        long[] dp = new long[100001];
        for(int i=0;i<dp.length;i++)
        {
            if(i<k)
            {
                dp[i] = 1;
            }
            else{
                dp[i] = (dp[i-1]%mod+dp[i-k]%mod)%mod;
            }
        }
        for(int i=1;i<dp.length;i++)
        {
            dp[i]=(dp[i]%mod+dp[i-1]%mod)%mod;
        }
        for(int x=0;x<t;x++)
        {
            int a = in.nextInt();
            int b = in.nextInt();
            long res = (dp[b] - dp[a-1]+mod)%mod;
            out.printLine(res);
        }
        out.flush();
        out.close();
    }
}


#include <bits/stdc++.h>
#define rep(x,n) for(int x=0;x<int(n);++x)
#define print(x) cout<<x<<endl
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define pv(x,y) {for(typeof(y) z=(x);z!=(y);z++)cerr<<*z<<" ";cerr<<endl;}
#define _ <<" , "<<
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef pair<int,int> pt;

int a[5555], n;

int main() {
  if(true) cin.sync_with_stdio(false);
  cin>>n;

  int fmin=0,cnt=1;

  rep(i,n) {
    cin>>a[i];
    fmin += abs(a[i]-i);
  }

  int pre=fmin;

  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++) if(j!=i) {
      int opa=pre;
      opa -= abs(a[i]-i);
      opa -= abs(a[j]-j);
      opa += abs(a[i]-j);
      opa += abs(a[j]-i);
      if(opa<fmin) fmin=opa,cnt=0;
      if(opa==fmin) cnt++;
    }
  }

  assert(fmin%2 == 0);

  print(fmin/2 << " " << cnt/2);

  return 0;
}


#include <bits/stdc++.h>
#define rep(x,n) for(int x=0;x<int(n);++x)
#define print(x) cout<<x<<endl
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define pv(x,y) {for(typeof(y) z=(x);z!=(y);z++)cerr<<*z<<" ";cerr<<endl;}
#define _ <<" , "<<
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef pair<int,int> pt;

int a[5555], n;
int f[5555];

int main() {
  if(true) cin.sync_with_stdio(false);
  cin>>n;
  rep(i,n) {
    cin>>a[i];
    f[a[i]]=i;
  }

  int fmin=0,cnt=1;
  for(int i=0;i<n;i++) fmin+=abs(i-f[i]);

  int pre=fmin;

  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++) {
      int opa=pre;
      opa -= abs(i-f[i]);
      opa -= abs(j-f[j]);
      swap(f[i],f[j]);
      opa += abs(i-f[i]);
      opa += abs(j-f[j]);
      swap(f[i],f[j]);
      if(opa<fmin) fmin=opa,cnt=0;
      if(opa==fmin) cnt++;
    }
  }

  dbg(fmin _ cnt);

  print(fmin/2 << " " << cnt);

  return 0;
}


#include <bits/stdc++.h>
#define rep(x,n) for(int x=0;x<int(n);++x)
#define print(x) cout<<x<<endl
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define pv(x,y) {for(auto z=(x);z!=(y);z++)cerr<<*z<<" ";cerr<<endl;}
#define _ <<" , "<<
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef pair<int,int> pt;

int a[5555], b[5555][5555], n;

int getmai(int i, int j, int k) {
  if(i>j) return 0;
  return b[k][j] - (i == 0 ? 0 : b[k][i-1]);
}

int getmen(int i, int j, int k) {
  if(i>j) return 0;
  int sz=j-i+1;
  return sz - getmai(i,j,k) - (i<=k and k<=j?1:0); // equal
}

int main() {
  if(true) cin.sync_with_stdio(false);

  cin>>n;

  int fmin=0,cnt=1;

  rep(i,n) {
    cin>>a[i];
  }

  rep(i,n) {
    rep(j,n) {
      b[i][j] = a[j]>a[i];
      if(j) b[i][j] += b[i][j-1];
    }
    fmin += b[i][i];
  }

  int pre=fmin;

  dbg(pre);

  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++) {
      int opa=pre;

//      dbg(i _ a[i] _ j _ a[j]);
  //    dbg( getmai(0,i,i) );
    //  dbg( getmai(0,j,j) );

      opa -= getmai(0,i,i);
      opa -= getmai(0,j,j);

      opa += getmai(0,j,i);
      opa += getmai(0,i-1,j);

      opa -= getmen(i+1,j-1,i);
      opa += getmen(i+1,j-1,j);

      if(opa<fmin) fmin=opa,cnt=0;
      if(opa==fmin) cnt++;
    }
  }

  pair<int,int> my(fmin,cnt);

  print(my.x << " " << my.y);

  return 0;
}


#include <bits/stdc++.h>
#define rep(x,n) for(int x=0;x<int(n);++x)
#define print(x) cout<<x<<endl
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define pv(x,y) {for(typeof(y) z=(x);z!=(y);z++)cerr<<*z<<" ";cerr<<endl;}
#define _ <<" , "<<
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef pair<int,int> pt;

int a[5555], n;

int main() {
  if(true) cin.sync_with_stdio(false);
  cin>>n;

  int fmin=0,cnt=1;

  rep(i,n) {
    cin>>a[i];
    fmin += abs(a[i]-i);
  }

  int pre=fmin;

  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++) {
      int opa=pre;
      opa -= abs(a[i]-i);
      opa -= abs(a[j]-j);
      opa += abs(a[i]-j);
      opa += abs(a[j]-i);
      if(opa<fmin) fmin=opa,cnt=0;
      if(opa==fmin) cnt++;
    }
  }

  assert(fmin%2 == 0);

  print(fmin/2 << " " << cnt);

  return 0;
}


/*
user  : triveni
date  : 02/03/2015
time  : 02:12:46
*/
#include <bits/stdc++.h>

using namespace std;

#define      pii               std::pair<int,int>
#define      vi                std::vector<int>
#define      mp(a,b)           std::make_pair(a,b)
#define      pb(a)             std::push_back(a)
#define      each(it,s)        for(auto it = s.begin(); it != s.end(); ++it)
#define      rep(i, n)         for(int i = 0; i < (n); ++i)
#define      fill(a)           memset(a, 0, sizeof (a))
#define      sortA(v)          sort(v.begin(), v.end())
#define      sortD(v)          sort(v.begin(), v.end(), greater<auto>())
#define      X                 first
#define      Y                 second

typedef long long LL;
LL MOD = 1000000007;
int dp[5000][5000];
int a[5000];

int getLessCount(int l, int r, int v){
	if(r < l) return 0;
	return dp[r][v] - (l > 0 ? dp[l-1][v] : 0);
}

int getGreatCount(int l, int r, int v){
	if(r < l) return 0;
	return r - l + 1 - (dp[r][v] - (l > 0 ? dp[l-1][v] : 0));
}

int getSwapCount(int l, int r){
	int ans = getLessCount(l+1, r-1, a[r]);
	ans += getGreatCount(l+1, r, a[l]);
	ans -= getGreatCount(l, r-1, a[r]);
	ans -= getLessCount(l+1, r-1, a[l]);
	return ans;
}

int main()
{
	int n;
	cin >> n;
	rep(i, n) cin >> a[i];
	for(int i = 0; i < n; ++i){
		dp[0][i] = (a[0] < i);
	}
	for(int i = 1; i < n; ++i){
		for(int j = 0; j < n; ++j){
			dp[i][j] = dp[i-1][j] + (a[i] < j);
		}
	}
	int ans = MOD, pairCount = 0;
	for(int i = 0; i < n; ++i){
		for(int j = i + 1; j < n; ++j){
			int s = getSwapCount(i, j);
			if(s < ans) ans = s, pairCount = 1;
			else if(s == ans) pairCount += 1;
		}
	}
	for(int i = 0; i < n; ++i){
		for(int j = 0; j < i; ++j){
			if(a[j] > a[i]) ans += 1;
		}
	}
	cout << ans << " " << pairCount << endl;
	return 0;
}


#include <cstdio>
#include <utility>
#include <vector>
#include <string>
#include <memory.h>
#include <iostream>
#include <assert.h>

using namespace std;

const int MAXN = 5100;
int a[MAXN];

int gr_cnt[MAXN][MAXN];
int less_cnt[MAXN][MAXN];

inline int seg(int (&mas)[MAXN], int l, int r)
{
    return mas[r] - (l ? mas[l - 1] : 0);
}

void check(int n)
{
    vector<int> a(::a, ::a + n);
    swap(a[0], a[4]);
    for (int i = 1; i < n; i = i + 1)
    {
       int j = i;
       while (j > 0 && a[j] < a[j - 1])
       {
          cerr << a[j] << " " << a[j - 1] << endl;
          swap(a[j], a[j - 1]);
          j = j - 1;
       }
    }
}

int main()
{
#ifdef LOCAL
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif
    int n;
    scanf("%d", &n);

    for(int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < n; ++j)
        {
            gr_cnt[i][j] = (j ? gr_cnt[i][j - 1] : 0) + int(a[j] > i);
            less_cnt[i][j] = (j ? less_cnt[i][j - 1] : 0) + int(a[j] < i);
        }
    }

    int swap_cnt = 0;
    for(int i = 0; i < n; ++i)
        swap_cnt += seg(less_cnt[a[i]], i, n - 1);

    int min_dif = 0;
    int min_dif_cnt = 0;
    for(int i = 0; i < n; ++i)
        for(int j = i + 1; j < n; ++j)
        {
            int dif_i = seg(less_cnt[a[i]], j + 1, n - 1) - seg(less_cnt[a[i]], i, n - 1) + seg(gr_cnt[a[i]], i, j - 1);
            int dif_j = (seg(less_cnt[a[j]], i + 1, n - 1) + int(a[i] < a[j])) - seg(less_cnt[a[j]], j, n - 1) - seg(gr_cnt[a[j]], i + 1, j);

            int dif = dif_i + dif_j;
            if(dif < min_dif)
            {
                min_dif = dif;
                min_dif_cnt = 1;
            }
            else if(dif == min_dif)
            {
                ++min_dif_cnt;
            }
        }

    printf("%d %d\n", swap_cnt + min_dif, min_dif_cnt);

    return 0;
}


//==================================
//==========   WARNING   ===========
//==================================
//===   Contains too many bugs   ===
//==================================

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <set>
#include <functional>
#include <queue>
#include <iomanip>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pr;
typedef pair<ll,ll> prl;

#define double long double

const ll mod7 = 1000000007;

#define NAME "string"

int arr[5000];

int data[5005][5005];
int data2[5005][5005];

int main()
{
    //freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
    //freopen(NAME".in","r",stdin); freopen(NAME".out","w",stdout);

    int n;
    scanf("%d",&n);

    for(int i=1;i<=n;++i)
    {
        scanf("%d",&arr[i]);
        ++data[i][arr[i]];
    }
    int ans = 0;
    int dif = -1;
    int cnt = 0;
    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j)
            if(arr[i]>arr[j])
                ++ans;
    for(int i=2;i<=n+2;++i)
    {
        for(int j=n-1;j>=0;--j)
            data2[i-1][j] = data2[i-1][j+1] + data[i-1][j];
        if(i>1)
        for(int j=n;j>=0;--j)
            data2[i-1][j] += data2[i-2][j];
    }

    for(int i=1;i<=n;++i)
    {
        for(int j=i+1;j<=n;++j)
        {
            if(i==j) continue;
            int a = (data2[j-1][arr[j]+1] - data2[i-1][arr[j]+1]);
            int b = (data2[j-1][arr[i]+1] - data2[i-1][arr[i]+1]);
            int c = ((data2[j-1][0] - data2[j-1][arr[j]]) - (data2[i-1][0]-data2[i-1][arr[j]]));
            int d = ((data2[j-1][0] - data2[j-1][arr[i]]) - (data2[i-1][0]-data2[i-1][arr[i]]));

            int res = a - b - c + d;

            if(res>=0)
            {
                if(res>dif)
                {
                    dif = res;
                    cnt = 1;
                }
                else if(res==dif)
                    ++cnt;
            }
        }
    }

    printf("%d %d",ans-dif,cnt);
    return 0;
}


#include <iostream>
#include <vector>
#include <climits>
using namespace std;

typedef vector < vector < unsigned > > matrix;

int main() {
    size_t size;
    std::cin >> size;
    vector < size_t > permutation(size);
    for (auto& elem : permutation) {
        std::cin >> elem;
    }
    matrix ok_with_left(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    matrix ok_with_right(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            ok_with_left[i][j] =
                ok_with_left[i][j - 1] + (permutation[i] < permutation[j]);
        }
    }
    for (size_t j = permutation.size() - 1; j + 1 != 0; --j) {
        for (size_t i = j - 1; i + 1 != 0; --i) {
            ok_with_right[i][j] =
                ok_with_right[i  + 1][j] + (permutation[i] < permutation[j]);
        }
    }

    int min_permutation_cost = INT_MIN;
    unsigned min_permutation_trans = 1;
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            int length = j - i;
            int curr_cost = length - 2 * ok_with_left[i][j]
                + length - 2 * ok_with_right[i][j];
            if (curr_cost > min_permutation_cost) {
                min_permutation_cost = curr_cost;
                min_permutation_trans = 1;
            } else if (curr_cost == min_permutation_cost) {
                ++min_permutation_trans;
            }
        }
    }
    int permutation_cost = 0;
    for (size_t i = 0; i < permutation.size(); ++i) {
        permutation_cost += (i - ok_with_right[0][i]);
    }
    std::cout << std::endl
              << permutation_cost - min_permutation_cost + 1
              << " "
              << min_permutation_trans
              << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <climits>
using namespace std;

typedef vector < vector < unsigned > > matrix;

long long main() {
    size_t size;
    std::cin >> size;
    vector < size_t > permutation(size);
    for (auto& elem : permutation) {
        std::cin >> elem;
    }
    matrix ok_with_left(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    matrix ok_with_right(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            ok_with_left[i][j] =
                ok_with_left[i][j - 1] + (permutation[i] < permutation[j]);
        }
    }
    for (size_t j = permutation.size() - 1; j + 1 != 0; --j) {
        for (size_t i = j - 1; i + 1 != 0; --i) {
            ok_with_right[i][j] =
                ok_with_right[i  + 1][j] + (permutation[i] < permutation[j]);
        }
    }

    long long min_permutation_cost = long long_MIN;
    unsigned min_permutation_trans = 1;
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            long long length = j - i;
            long long curr_cost = length - 2 * ok_with_left[i][j]
                + length - 2 * ok_with_right[i][j];
            if (curr_cost > min_permutation_cost) {
                min_permutation_cost = curr_cost;
                min_permutation_trans = 1;
            } else if (curr_cost == min_permutation_cost) {
                ++min_permutation_trans;
            }
        }
    }
    long long permutation_cost = 0;
    for (size_t i = 0; i < permutation.size(); ++i) {
        permutation_cost += (i - ok_with_right[0][i]);
    }
    std::cout << std::endl
              << permutation_cost - min_permutation_cost + 1
              << " "
              << min_permutation_trans
              << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
using namespace std;

typedef vector < vector < unsigned > > matrix;

int main() {
    size_t size;
    std::cin >> size;
    vector < size_t > permutation(size);
    for (auto& elem : permutation) {
        std::cin >> elem;
    }
    matrix ok_with_left(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    matrix ok_with_right(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            ok_with_left[i][j] =
                ok_with_left[i][j - 1] + (permutation[i] < permutation[j]);
        }
    }
    for (size_t j = permutation.size() - 1; j + 1 != 0; --j) {
        for (size_t i = j - 1; i + 1 != 0; --i) {
            ok_with_right[i][j] =
                ok_with_right[i  + 1][j] + (permutation[i] < permutation[j]);
        }
    }

    long long min_permutation_cost = 0;
    unsigned min_permutation_trans = 1;
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            long long length = j - i;
            long long curr_cost = length - 2 * ok_with_left[i][j]
                + length - 2 * ok_with_right[i][j];
            std::cerr << "CURR COST IS " << i << " " << j << " " << curr_cost << "\n";
            if (curr_cost > min_permutation_cost) {
                min_permutation_cost = curr_cost;
                min_permutation_trans = 1;
            } else if (curr_cost == min_permutation_cost) {
                ++min_permutation_trans;
            }
        }
    }
    long long permutation_cost = 0;
    for (size_t i = 0; i < permutation.size(); ++i) {
        permutation_cost += (i - ok_with_right[0][i]);
    }
    std::cout << std::endl
              << permutation_cost - min_permutation_cost + 1
              << " "
              << min_permutation_trans
              << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <climits>
using namespace std;

typedef vector < vector < unsigned > > matrix;

int main() {
    size_t size;
    std::cin >> size;
    vector < size_t > permutation(size);
    for (auto& elem : permutation) {
        std::cin >> elem;
    }
    matrix ok_with_left(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    matrix ok_with_right(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            ok_with_left[i][j] =
                ok_with_left[i][j - 1] + (permutation[i] < permutation[j]);
        }
    }
    for (size_t j = permutation.size() - 1; j + 1 != 0; --j) {
        for (size_t i = j - 1; i + 1 != 0; --i) {
            ok_with_right[i][j] =
                ok_with_right[i  + 1][j] + (permutation[i] < permutation[j]);
        }
    }

    int min_permutation_cost = INT_MIN;
    unsigned min_permutation_trans = 1;
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            int length = j - i;
            int curr_cost = length - 2 * ok_with_left[i][j]
                + length - 2 * ok_with_right[i][j];
            std::cerr << "CURR COST IS " << i << " " << j << " " << curr_cost << "\n";
            if (curr_cost > min_permutation_cost) {
                min_permutation_cost = curr_cost;
                min_permutation_trans = 1;
            } else if (curr_cost == min_permutation_cost) {
                ++min_permutation_trans;
            }
        }
    }
    int permutation_cost = 0;
    for (size_t i = 0; i < permutation.size(); ++i) {
        permutation_cost += (i - ok_with_right[0][i]);
    }
    std::cout << std::endl
              << permutation_cost - min_permutation_cost + 1
              << " "
              << min_permutation_trans
              << std::endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <climits>
using namespace std;

typedef vector < vector < unsigned > > matrix;

int main() {
    size_t size;
    std::cin >> size;
    vector < size_t > permutation(size);
    for (auto& elem : permutation) {
        std::cin >> elem;
    }
    matrix ok_with_left(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    matrix ok_with_right(permutation.size(),
        vector < unsigned > (permutation.size(), 0));
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            ok_with_left[i][j] =
                ok_with_left[i][j - 1] + (permutation[i] < permutation[j]);
        }
    }
    for (size_t j = permutation.size() - 1; j + 1 != 0; --j) {
        for (size_t i = j - 1; i + 1 != 0; --i) {
            ok_with_right[i][j] =
                ok_with_right[i  + 1][j] + (permutation[i] < permutation[j]);
        }
    }

    long long min_permutation_cost = INT_MIN;
    unsigned min_permutation_trans = 1;
    for (size_t i = 0; i < permutation.size(); ++i) {
        for (size_t j = i + 1; j < permutation.size(); ++j) {
            long long length = j - i;
            long long curr_cost = length - 2 * ok_with_left[i][j]
                + length - 2 * ok_with_right[i][j];
            if (curr_cost > min_permutation_cost) {
                min_permutation_cost = curr_cost;
                min_permutation_trans = 1;
            } else if (curr_cost == min_permutation_cost) {
                ++min_permutation_trans;
            }
        }
    }
    long long permutation_cost = 0;
    for (size_t i = 0; i < permutation.size(); ++i) {
        permutation_cost += (i - ok_with_right[0][i]);
    }
    std::cout << std::endl
              << permutation_cost - min_permutation_cost + 1
              << " "
              << min_permutation_trans
              << std::endl;
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstddef>
#include <complex>
#include <ctime>
#include <climits>

#include <algorithm>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <functional>
#include <iterator>
#include <typeinfo>
#include <utility>
#include <memory>

#include <cassert>

#if __cplusplus >= 201103L
#include <tuple>
#include <ratio>
#include <array>
#include <forward_list>
#include <unordered_map>
#include <unordered_set>
#endif
using namespace std;

typedef long long int64;
const int inf = 2000000000;
static inline int Rint()
{
	struct X{ int dig[256]; X(){
	for(int i = '0'; i <= '9'; ++i) dig[i] = 1; dig['-'] = 1;
	}};
	static 	X fuck;int s = 1, v = 0, c;
	for (;!fuck.dig[c = getchar()];);
	if (c == '-') s = 0; else if (fuck.dig[c]) v = c ^ 48;
	for (;fuck.dig[c = getchar()]; v = v * 10 + (c ^ 48));
	return s ? v : -v;
}
typedef vector<int> vi;
typedef map<int, int> mii;
typedef set<int> si;

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, s, e) for (int i = (s); i < (e); ++i)

#if __cplusplus >= 201103L
#define foreach(iter, c) for(auto& iter : c)
#else
#define foreach(itr, c) for(__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); ++itr)
#endif

template<typename T> static inline void cmax(T& a, const T& b){if(b>a)a=b;}
template<typename T> static inline void cmin(T& a, const T& b){if(b<a)a=b;}
#define SL static inline

#define dbg(x) cerr << (#x) << " = " << (x) << endl

const int maxn = 100005;

int data[5005];

int tree[5005];

SL void update(int x)
{
	for (; x; x -= x &-x) ++tree[x];
}
SL int query(int x, int n)
{
	int ret = 0;
	for (; x <= n; x += x &-x) ret += tree[x];
	return ret;
}
int main()
{
	const int n = Rint();
	rep(i, 0, n) data[i] = Rint() + 1;

	int total = 0;
	for (int i = 0; i < n; ++i)
	for (int j = 0; j < i; ++j)
	total += data[j] > data[i];

	int best = 0, cnt = 0;
	for (int l = 0; l < n; ++l)
	{
		int less_than = 0;
		fill(tree, tree+1+n, 0);
		for (int r = l + 1; r < n; ++r)
		{
			int x = r - l;
			less_than += data[r] < data[l];
			int greater = query(data[r], n);
			int t = - (x-less_than) + less_than -(x-1-greater) + greater;
			if (t > best) best = t, cnt = 1;
			else if (t == best) ++cnt;
			update(data[r]);
		}
	}
	printf("%d %d\n", total - best, cnt);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>
#include <memory>
#include <queue>
#include <list>
#include <numeric>
#include <stack>

using namespace std;

#define MAX 1000000000
#define MIN INT_MIN
#define FOR(i,a,n) for(int i = a; i < n; ++i)
#define ull unsigned long long
#define ll long long
#define sqr(x) ((x) * (x))
#define pi 3.14159265

const int size = 5007;
int p[size];
int dp[size][size];
int totalInv = 0;

int main(){
	int n;
	cin>>n;
	FOR(i,0,n) cin>>p[i];
	FOR(i,0,n)
		FOR(j,i+1,n)
			totalInv += (p[j] < p[i]);
	FOR(j,0,n){
		dp[0][j] = (p[0] < j);
		FOR(i,1,n){
			dp[i][j] = dp[i-1][j] + (p[i] < j);
		}
	}
	int ans = totalInv,cnt = 0;
	FOR(i,0,n-1){
		FOR(j,i+1,n){
			if(p[i] > p[j]){
				int curr = totalInv + 2 * (dp[j][p[j]] + dp[i][p[i]] - dp[j][p[i]] - dp[i][p[j]]) + 1;
				if(curr == ans) ++cnt;
				else if(curr < ans){
					ans = curr;
					cnt = 1;
				}
			}
		}
	}
	cout<<ans<<' '<<cnt<<endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>
#include <memory>
#include <queue>
#include <list>
#include <numeric>
#include <stack>

using namespace std;

#define MAX 1000000000
#define MIN INT_MIN
#define FOR(i,a,n) for(int i = a; i < n; ++i)
#define ull unsigned long long
#define ll long long
#define sqr(x) ((x) * (x))
#define pi 3.14159265

const int size = 5007;
//vector<int> suff[size];
int p[size];
int inv[size];
int totalInv = 0;

int main(){
	int n;
	cin>>n;
	FOR(i,0,n) cin>>p[i];
	//FOR(i,0,n){
	//	FOR(j,i+1,n)
	//		suff[i].push_back(p[j]);
	//	sort(suff[i].begin(),suff[i].end());
	//}
	FOR(i,0,n){
		FOR(j,i+1,n){
			inv[i] += (p[j] < p[i]);
		}
		totalInv += inv[i];
	}
	int mx = *max_element(inv,inv + size);
	int ans = totalInv,cnt = 0;
	vector<int> bad;
	FOR(i,0,n){
		if(inv[i] == mx) bad.push_back(i);
	}
	FOR(i,0,bad.size()){
		int pos = i;
		FOR(pos,i+1,n){
			if(p[bad[i]] > p[pos]){
			int curr = totalInv;
			int c1 = 0,c2 = 0,c3 = 0,c4 = 0;
			FOR(j,i+1,pos){
				c1 += (p[j] > p[pos]);
				c2 += (p[j] < p[pos]);
				c3 += (p[j] > p[bad[i]]);
				c4 += (p[j] < p[bad[i]]);
			}
			curr -= c1;
			curr += c2;
			curr += c3;
			curr -= c4;
			--curr;
			if(curr < ans){
				ans = curr;
				cnt = 1;
			} else if(curr == ans) ++cnt;
			}
		}

		/*FOR(j,i+1,n){
			if(p[i] > p[j]){
				int curr = totalInv - inv[i] - inv[j];
				if(j != n-1){
					int c1 = (int)(lower_bound(suff[j].begin(),suff[j].end(),p[i]) - suff[j].begin());
					curr += c1;
				}
				int c2 = (int)(lower_bound(suff[i].begin(),suff[i].end(),p[j]) - suff[i].begin());
				curr += c2;
				if(curr < ans){
					ans = curr;
					cnt = 1;
				} else if(curr == ans) ++cnt;
			}
		}*/
	}
	cout<<ans<<' '<<cnt<<endl;
	return 0;
}


#include <stdio.h>
#define MAXN 5033
int dp[MAXN][MAXN];
int num[MAXN];
int n;

int main()
{
	int i,j;
	int tot=0;
	int min,cnt;
	int result;

	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&num[i]);
	for(i=0;i<n;i++)
	{
		for(j=i+1;j<n;j++)dp[i][j]=dp[i][j-1]+(num[j]<num[i]);
		for(j=i-1;j>=0;j--)dp[i][j]=dp[i][j+1]+(num[j]<num[i]);
		tot+=dp[i][n-1];
	}
	min=n*n;
	for(i=0;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		{
			if(num[i]>num[j])
			{
				result=tot-2*(dp[i][j-1]-dp[j][i+1])-1;
				if(result<min)min=result,cnt=0;
				if(result==min)++cnt;
			}
		}
	}
	printf("%d %d\n",min,cnt);
	/** /
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			printf("%d ",dp[i][j]);
		}
		puts("");
	}
	printf("tot %d\n",tot);
	/**/
	return 0;
}


#include <stdio.h>

int tree[16384];

void add(int idx, int l, int r, int a)
{
	int mid;
	tree[idx]++;
	if(l < r)
	{
		mid = l + (r - l) / 2;
		if(a <= mid)
			add(idx * 2 + 1, l, mid, a);
		else
			add(idx * 2 + 2, mid + 1, r, a);
	}
}

int get(int idx, int l, int r, int a)
{
	int mid;
	if(a == l)
		return tree[idx];
	mid = l + (r - l) / 2;
	if(a <= mid)
		return get(idx * 2 + 1, l, mid, a) + tree[idx * 2 + 2];
	return get(idx * 2 + 2, mid + 1, r, a);
}

void clear(int idx, int l, int r)
{
	int mid;
	tree[idx] = 0;
	if(l < r)
	{
		mid = l + (r - l) / 2;
		clear(idx * 2 + 1, l, mid);
		clear(idx * 2 + 2, mid + 1, r);
	}
}

int main()
{
	int i, j;
	int n;
	int a[5000];
	int sum = 0;
	int maxcount = -1;
	int res;
	int count;
#ifndef ONLINE_JUDGE
	freopen("E:\\tmp\\in", "r", stdin);
	freopen("E:\\tmp\\out", "w", stdout);
#endif
	scanf("%d", &n);
	for(i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		for(j = 0; j < i; j++)
			if(a[j] > a[i])
				sum++;
	}
	for(i = 0; i < n - 1; i++)
	{
		clear(0, 0, n - 1);
		for(j = i + 1; j < n; j++)
		{
			if(a[j] < a[i]){
				count = get(0, 0, n - 1, a[j]);
				if(count > maxcount)
				{
					maxcount = count;
					res = 1;
				}
				else if(count == maxcount)
					res++;
				add(0, 0, n - 1, a[j]);
			}
		}
	}
	printf("%d %d", sum - maxcount * 2 - 1, res);
	return 0;
}


#include <stdio.h>

int main()
{
	int i, j;
	int n;
	int a[5000];
	int last[5000];
	int sum = 0;
	int maxcount = -1;
	int res;
	int count[5000];
#ifndef ONLINE_JUDGE
	freopen("E:\\tmp\\in", "r", stdin);
	freopen("E:\\tmp\\out", "w", stdout);
#endif
	scanf("%d", &n);
	for(i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		last[i] = -1;
		for(j = 0; j < i; j++)
			if(a[j] > a[i])
			{
				last[i] = j;
				sum++;
			}
	}
	for(i = 0; i < n - 1; i++)
	{
		count[i] = 0;
		for(j = i + 1; j < n; j++)
		{
			if(last[j] < i)
				count[j] = 0;
			else
				count[j] = count[last[j]] + 1;
			if(count[j] > maxcount)
			{
				maxcount = count[j];
				res = 1;
			}
			else if(count[j] == maxcount)
				res++;
		}
	}
	printf("%d %d", sum - maxcount * 2 + 1, res);
	return 0;
}


#include <stdio.h>

int seq[5000];
int morebef[5001][5000];
//          ind   num
int main()
{
    int n;
    int i, j;
    scanf("%d", &n);
    int min, count, ans = 0;
    for(i = 0; i < n; i++)
    {
        scanf("%d", &seq[i]);
        for(j = 0; j < n; j++)
        {
            morebef[i + 1][j] = morebef[i][j] + ((j < seq[i]) ? 1 : 0);
        }
        ans += morebef[i][seq[i]];
    }
    min = ans;
    count = 0;
    int buf;
    for(i = 0; i < n; i++)
    {
        for(j = i + 1; j < n; j++)
        {
            buf = ans - morebef[i][seq[i]] - morebef[j][seq[j]] - (n - i - 1 - (i - morebef[i][seq[i]])) - (n - j - 1 - (j - morebef[j][seq[j]])) + morebef[i][seq[j]] + morebef[j][seq[i]] + (n - i - 1 - (i - morebef[i][seq[j]])) + (n - j - 1 - (j - morebef[j][seq[i]])) + ((seq[i] > seq[j]) ? 1 : 0);
            if(buf < min)
            {
                min = buf;
                count = 1;
            }
            else if (buf == min)
            {
                count++;
            }
        }
    }
    printf("%d %d", min, count);
    return 0;
}


import java.util.Scanner;

public class C {
    public static void main(String cd[]){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int a[]=new int[n];
        for(int i=0;i<n;i++){
            a[i]=in.nextInt();
        }
        int dp[][]=new int[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i!=0)
                dp[i][j]=dp[i-1][j];

                if(a[i]>j){
                    dp[i][j]++;
                }
        //      System.out.print(dp[i][j]+" ");
            }
        //  System.out.println();
        }
        int max=0;
        int no=0;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(a[i]>a[j]){
                    int dec=2*(dp[i][a[i]]+dp[j][a[j]]-dp[i][a[j]]-dp[j][a[i]])+1;
                //  System.out.println(dec+ " "+max);
                    if(dec>max){
                        max=dec;
                        no=1;
                    }
                    else if(dec==max){
                        no++;
                    }
                }
            }
        }
        int total=0;
        for(int i=0;i<n;i++){
            total+=dp[i][a[i]];
        }
        //System.out.println(total);
        System.out.println(total-max+" "+no);
    }
}


import java.util.Scanner;

public class C {
    public static void main(String cd[]){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int a[]=new int[n];
        long sum=0;
        for(int i=0;i<n;i++){
            a[i]=in.nextInt();
            sum+=Math.abs(a[i]-i);
        }
        //System.out.println(sum);
        long min=Integer.MAX_VALUE;
        int no=0;
        for(int i=0;i<n;i++){
            for(int j=i;j<n;j++){
                long s=sum;
                s-=Math.abs(a[i]-i)+Math.abs(a[j]-j);
                s+=Math.abs(a[i]-j)+Math.abs(a[j]-i);
                //System.out.println(s+" "+min);
                if(s<min){
                    min=s;
                    no=1;
                }
                else if(s==min){
                    min=s;
                    no++;
                }

            }
        }
        System.out.println(min/2+" "+no);

    }
}


import java.util.Scanner;

public class C_212 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int d[][] = new int[n][n];
		int [] perm = new int[n];
		for(int i = 0; i < n; i++){
			perm[i] = in.nextInt();
		}

		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(i == 0){
					if(j < perm[i]) d[i][j] = 1;
					else d[i][j] = 0;
				} else {
					if(j < perm[i]) d[i][j] = d[i-1][j]+1;
					else d[i][j] = d[i-1][j];
				}
			}
		}
		int swaps = 0;
		for(int i = 0; i < perm.length; i++){
			swaps += d[i][perm[i]];
		}

		int best = Integer.MAX_VALUE;
		int pairs = 0;
		for(int i = 0; i < n; i++){
			for(int j = i+1; j < n; j++){
				int val = swaps-2*(+d[i][perm[i]]-d[j][perm[i]] + d[j][perm[j]]-d[i][perm[j]]) -1;
				if(val < best){
					best = val;
					pairs = 1;
				} else if(val == best){
					pairs++;
				}
			}
		}
		System.out.println(best + " " + pairs);
	}
}