#include <bits/stdc++.h>
using namespace std;
typedef priority_queue<long long, vector<long long>> decendingQueue;
typedef priority_queue<long long, vector<long long>, greater<long long>>
    ascendingQueue;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const long long INF = 9 * 1e18;
const long long MOD = 1e9 + 7;
long long gcd(long long m, long long n) {
  if (m < n) return gcd(n, m);
  if (n == 0) return m;
  return gcd(n, m % n);
}
long long lcm(long long m, long long n) { return m * (n / gcd(m, n)); }
long long addMod(long long a, long long b) { return (a + b) % MOD; }
long long minusMod(long long a, long long b) { return (a + MOD - b) % MOD; }
long long multipleMod(long long a, long long b) { return (a * b) % MOD; }
vector<long long> SieveOfEratosthenes(int max) {
  vector<long long> sieve;
  vector<long long> primes;
  for (int i = 1; i < max + 1; ++i) {
    sieve.push_back(i);
  }
  sieve[0] = 0;
  for (int i = 2; i < max + 1; ++i) {
    if (sieve[i - 1] != 0) {
      primes.push_back(sieve[i - 1]);
      for (int j = 2 * sieve[i - 1]; j < max + 1; j += sieve[i - 1]) {
        sieve[j - 1] = 0;
      }
    }
  }
  return primes;
}
class Combination {
 private:
  vector<long long> fac_;
  vector<long long> finv_;
  vector<long long> inv_;
  long long prime_;

 public:
  Combination(long long n, long long prime) {
    fac_ = vector<long long>(n + 1);
    finv_ = vector<long long>(n + 1);
    inv_ = vector<long long>(n + 1);
    prime_ = prime;
    fac_[0] = fac_[1] = 1;
    finv_[0] = finv_[1] = 1;
    inv_[1] = 1;
    for (long long i = 2; i <= n; i++) {
      fac_[i] = fac_[i - 1] * i % prime_;
      inv_[i] = prime_ - inv_[prime_ % i] * (prime_ / i) % prime_;
      finv_[i] = finv_[i - 1] * inv_[i] % prime_;
    }
  }
  long long getCombination(long long n, long long k) {
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac_[n] * (finv_[k] * finv_[n - k] % prime_) % prime_;
  }
};
class UnionFindTree {
 private:
  vector<int> par;
  vector<int> rnk;
  vector<int> siz;

 public:
  UnionFindTree(int n) {
    par.assign(n, -1);
    rnk.assign(n, -1);
    siz.assign(n, -1);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rnk[i] = 0;
      siz[i] = 1;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else {
      par[y] = x;
      siz[x] += siz[y];
      if (rnk[x] == rnk[y]) ++rnk[x];
    }
  }
  int size(int x) {
    x = find(x);
    return siz[x];
  }
};
class Edge {
 public:
  long long from;
  long long to;
  long long cost;
  Edge() {}
  Edge(long long from, long long to, long long cost) {
    this->from = from;
    this->to = to;
    this->cost = cost;
  }
  bool operator<(const Edge &edge) const { return cost < edge.cost; }
};
class Graph {
 public:
  long long nodes;
  vector<Edge> edges;
  Graph() {}
  Graph(long long nodes) { this->nodes = nodes; }
  void addEdge(long long from, long long to, long long cost) {
    this->edges.push_back(Edge(from, to, cost));
  }
};
class Kruskal {
 private:
  Graph graph;
  vector<Edge> MinimumSpanningTree;
  long long minimumCost;
  void searchMinimumSpanningTree() {
    UnionFindTree uf(graph.nodes);
    sort((graph.edges).begin(), (graph.edges).end());
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      if (!uf.same(edge->from, edge->to)) {
        uf.unite(edge->from, edge->to);
        MinimumSpanningTree.push_back(*edge);
      }
    }
  }

 public:
  Kruskal(Graph graph) { this->graph = graph; }
  long long getMinimumSpanningTreeCost() {
    searchMinimumSpanningTree();
    long long cost = 0;
    for (auto(it) = (MinimumSpanningTree).begin();
         (it) != (MinimumSpanningTree).end(); (it)++) {
      cost += it->cost;
    }
    return cost;
  }
};
class Dijkstra {
 private:
  Graph graph;
  map<long long, vector<Edge>> fromPaths;
  vector<long long> distances;
  vector<long long> srcs;

 public:
  Dijkstra(Graph graph) {
    this->graph = graph;
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      fromPaths[edge->from].push_back(*edge);
      fromPaths[edge->to].push_back(Edge(edge->to, edge->from, edge->cost));
    }
  }
  void searchMinimumPathFrom(long long src) {
    this->distances = vector<long long>(graph.nodes + 1, INF);
    this->srcs = vector<long long>(graph.nodes + 1, INF);
    priority_queue<long long> pq;
    distances[src] = 0;
    srcs[src] = -1;
    pq.push(src);
    while (!pq.empty()) {
      int u = pq.top();
      pq.pop();
      for (auto(edge) = (fromPaths[u]).begin(); (edge) != (fromPaths[u]).end();
           (edge)++) {
        int v = edge->to;
        int w = edge->cost;
        if (distances[v] > distances[u] + w) {
          distances[v] = distances[u] + w;
          srcs[v] = u;
          pq.push(v);
        }
      }
    }
  };
  long long getDistance(long long n) { return this->distances[n]; }
  long long getFrom(long long n) { return this->srcs[n]; }
};
class BellmanFord {
 private:
  Graph graph;
  vector<bool> hasNegativeCycles;
  vector<long long> distances;

 public:
  BellmanFord(Graph graph) {
    this->graph = graph;
    this->distances = vector<long long>(this->graph.nodes + 1, INF);
    this->hasNegativeCycles = vector<bool>(this->graph.nodes + 1, false);
  }
  void searchMinimumPathFrom(long long src) {
    this->distances[src] = 0;
    for (long long i = 0; i < graph.nodes - 1; i++) {
      for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
           (edge)++) {
        long long u = edge->from;
        long long v = edge->to;
        long long w = edge->cost;
        if (this->distances[u] + w < this->distances[v]) {
          this->distances[v] = this->distances[u] + w;
        }
      }
    }
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      long long u = edge->from;
      long long v = edge->to;
      long long w = edge->cost;
      if (this->distances[u] + w < this->distances[v]) {
        this->hasNegativeCycles[v] = true;
      }
      if (this->hasNegativeCycles[u] == true) {
        this->hasNegativeCycles[v] = true;
      }
    }
  }
  long long getDistance(long long n) { return this->distances[n]; }
  bool hasNegativeCycle(long long n) { return this->hasNegativeCycles[n]; }
};
void solve(long long N, std::vector<long long> A) {
  int BITS = 61;
  vector<long long> bits(BITS);
  for (int(j) = (0); (j) < (BITS); ++(j)) {
    for (int(i) = (0); (i) < (N); ++(i)) {
      if ((A[i] >> j) & 1) {
        bits[j]++;
      }
    }
    bits[j] *= N - bits[j];
  }
  for (int(j) = (1); (j) < (BITS); ++(j)) {
    bits[j] += bits[j - 1] / 2;
    bits[j - 1] = bits[j - 1] % 2;
  }
  long long ans = 0;
  for (int(j) = (0); (j) < (BITS); ++(j)) {
    ans = addMod(ans, multipleMod((1ll << j) % MOD, bits[j]));
  }
  cout << ans << endl;
}
int main() {
  long long N;
  scanf("%lld", &N);
  std::vector<long long> A(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &A[i]);
  }
  solve(N, std::move(A));
  return 0;
}
