#include <bits/stdc++.h>
using namespace std;
struct Node {
  long long actual, posible, pos;
  Node() { actual = 0, posible = 0, pos = 0; }
  Node(long long a, long long p, int i) : actual(a), posible(p), pos(i) {}
};
Node merge(Node &a, Node &b) {
  long long diffA = a.actual - a.posible;
  long long diffB = b.actual - b.posible;
  if (diffA > diffB) return Node(a.actual, a.posible, a.pos);
  return Node(b.actual, b.posible, b.pos);
}
struct STree {
  vector<Node> st;
  int n;
  STree(int n) : st(4 * n + 5), n(n) {}
  void upd(int k, int s, int e, int p, Node v) {
    if (s + 1 == e) {
      st[k] = v;
      return;
    }
    int m = (s + e) / 2;
    if (p < m)
      upd(2 * k, s, m, p, v);
    else
      upd(2 * k + 1, m, e, p, v);
    st[k] = merge(st[2 * k], st[2 * k + 1]);
  }
  Node query(int k, int s, int e, int a, int b) {
    if (s >= b || e <= a) return Node();
    if (s >= a && e <= b) return st[k];
    int m = (s + e) / 2;
    Node izq = query(2 * k, s, m, a, b);
    Node der = query(2 * k + 1, m, e, a, b);
    return merge(izq, der);
  }
  void upd(int p, Node v) { upd(1, 0, n, p, v); }
  Node query(int a, int b) { return query(1, 0, n, a, b); }
};
long long get(long long x, long long y) {
  y = min(x, y);
  long long r = x / y;
  long long resto = x % y;
  long long res = resto * (r + 1) * (r + 1) + (y - resto) * r * r;
  return res;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, k;
  cin >> n >> k;
  long long a[n];
  for (int i = 0; i < n; i++) cin >> a[i];
  STree rmq(n);
  long long res = 0;
  for (int i = 0; i < n; i++) {
    res += a[i] * a[i];
    rmq.upd(i, Node(a[i] * a[i], get(a[i], 2), i));
  }
  int partido[n];
  for (int i = 0; i < n; i++) partido[i] = 1;
  int faltan = k - n;
  while (faltan--) {
    auto node = rmq.query(0, n);
    res += node.posible - node.actual;
    rmq.upd(node.pos,
            Node(node.posible, get(a[node.pos], ++partido[node.pos] + 1),
                 node.pos));
  }
  cout << res << '\n';
  return 0;
}
