#include <bits/stdc++.h>
using namespace std;
const int Maxk = 1005;
string mul(string a, string b) {
  int res[Maxk];
  memset(res, 0, sizeof(res));
  reverse(a.begin(), a.end());
  reverse(b.begin(), b.end());
  for (int i = 0; i < a.length(); i++) {
    for (int j = 0; j < b.length(); j++) {
      res[i + j] += (a[i] - '0') * (b[j] - '0');
    }
  }
  for (int i = 0; i < Maxk; i++) {
    if (res[i] >= 10) {
      res[i + 1] += (res[i] / 10);
      res[i] %= 10;
    }
  }
  string ret;
  bool flag = false;
  for (int i = Maxk - 1; i >= 0; i--) {
    if (flag || res[i]) {
      flag = true;
      ret = ret + (char)(res[i] + '0');
    }
  }
  if (ret == "") ret = "0";
  return ret;
}
string add(string a, string b) {
  if (a.length() < b.length()) swap(a, b);
  while (a.length() != b.length()) {
    b = '0' + b;
  }
  for (int i = a.length() - 1; i >= 0; i--) {
    a[i] += (b[i] - '0');
    if (a[i] > '9' && i) {
      a[i] -= 10;
      a[i - 1]++;
    }
  }
  if (a[0] > '9') {
    a[0] -= 10;
    a = '1' + a;
  }
  return a;
}
struct node {
  int siz;
  node *l, *r;
  int ocr[33];
  node() {
    l = NULL;
    r = NULL;
    siz = 0LL;
    for (int i = 0; i <= 30; i++) ocr[i] = 0LL;
  }
} root;
const int Maxn = 50005;
const long long mod = 1000000007;
int a[Maxn];
long long final;
long long fuckyou;
int n;
long long m;
void add_occ(int val, node *&x) {
  for (int i = 30; i >= 0; i--) {
    if (val & (1 << i)) {
      x->ocr[i]++;
    }
  }
}
void ADD(int val) {
  node *now = &root;
  now->siz++;
  add_occ(val, now);
  for (int i = 30; i >= 0; i--) {
    if (val & (1 << i)) {
      if (now->r == NULL) {
        now->r = new node;
      }
      now = now->r;
    } else {
      if (now->l == NULL) {
        now->l = new node;
      }
      now = now->l;
    }
    now->siz++;
    add_occ(val, now);
  }
}
long long query(long long val, long long lim) {
  node *now = &root;
  long long res = 0;
  long long nv = 0;
  for (int i = 30; i >= 0; i--) {
    long long nb = (1 << i);
    if (val & (1 << i)) {
      if (nv + nb >= lim) {
        if (now->l != NULL) {
          res += now->l->siz;
        }
        if (now->r == NULL) {
          break;
        }
        now = now->r;
      } else {
        if (now->l == NULL) {
          break;
        }
        now = now->l;
        nv += nb;
      }
    } else {
      if (nv + nb >= lim) {
        if (now->r != NULL) {
          res += now->r->siz;
        }
        if (now->l == NULL) {
          break;
        }
        now = now->l;
      } else {
        if (now->r == NULL) {
          break;
        }
        now = now->r;
        nv += nb;
      }
    }
  }
  return res;
}
long long query2(int val, int lim) {
  node *now = &root;
  long long res = 0LL;
  long long nv = 0LL;
  for (int i = 30; i >= 0; i--) {
    long long nb = (1 << i);
    if (val & (1 << i)) {
      if (nv + nb >= lim) {
        if (now->l != NULL) {
          long long sizz = now->l->siz;
          long long tj = 1;
          for (int j = 0; j <= 30; j++) {
            if (val & tj) {
              res += tj * (sizz - now->l->ocr[j]);
            } else {
              res += tj * now->l->ocr[j];
            }
            tj <<= 1;
          }
        }
        if (now->r == NULL) {
          break;
        }
        now = now->r;
      } else {
        if (now->l == NULL) {
          break;
        }
        now = now->l;
        nv += nb;
      }
    } else {
      if (nv + nb >= (long long)lim) {
        if (now->r != NULL) {
          long long sizz = now->r->siz;
          long long tj = 1;
          for (int j = 0; j <= 30; j++) {
            if (val & tj) {
              res += tj * (long long)(sizz - now->r->ocr[j]);
            } else {
              res += tj * (long long)now->r->ocr[j];
            }
            tj <<= 1;
          }
        }
        if (now->l == NULL) {
          break;
        }
        now = now->l;
      } else {
        if (now->r == NULL) {
          break;
        }
        now = now->r;
        nv += nb;
      }
    }
  }
  return res;
}
bool check(long long lim) {
  long long tot = 0;
  for (int i = 0; i < n; i++) {
    tot += query((long long)a[i], lim);
  }
  tot /= 2;
  fuckyou = tot;
  return tot >= (long long)m;
}
void calc(int lim) {
  final = 0LL;
  for (int i = 0; i < n; i++) {
    long long nx = query2(a[i], lim);
    final += nx;
  }
}
int main() {
  scanf("%d %I64d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    ADD(a[i]);
  }
  long long l = 1, r = 2147483647;
  while (l < r - 1) {
    long long tmp = (long long)l + r;
    tmp /= 2;
    if (check(tmp)) {
      l = tmp;
    } else {
      r = tmp;
    }
  }
  long long md = 0;
  if (check(r)) {
    md = r;
  } else {
    md = l;
  }
  check(md);
  long long fuckk = 0LL;
  if (fuckyou > m) {
    fuckk = (long long)md * (long long)(fuckyou - m);
  }
  calc(md);
  final /= 2;
  final -= fuckk;
  printf("%I64d\n", final % mod);
  return 0;
}
