Problem: Alice and Bob decided to play one ultimate game. They have n piles, the i-th pile initially contain v_i chips. Alice selects a positive integer a from interval [1, m], and Bob selects a number b the same way. 

Then the game starts. In her turn, Alice can select any pile containing at least a chips, and remove exactly a chips from it. Similarly, in his turn, Bob can choose any pile with at least b chips, and remove exactly b chips from it. If a player cannot make a move, he or she loses. 

If both players play optimally, the outcome ultimately depends on the choice of a and b, and on the starting player. Consider a fixed pair (a,b). There are four types of games: 

  * Alice wins, regardless of who starts. 
  * Bob wins, regardless of who starts. 
  * If Alice starts, she wins. If Bob starts, he wins. We say that the first player wins. 
  * If Alice starts, Bob wins. If Bob starts, Alice wins. We say that the second player wins. 



Among all choices of a and b (i.e. for each pair (a, b) such that 1≤ a, b≤ m), determine how many games are won by Alice (regardless of who starts), how many are won by Bob (regardless of who starts), how many are won by the first player, and how many are won by the second player. 

Input

The first line contains two integers n and m (1 ≤ n ≤ 100, 1 ≤ m ≤ 10^5) — the number of piles, and the upper bound on the number of chips allowed to be taken in one turn, respectively. 

The second line contains n integers v_1, v_2, ..., v_n (1 ≤ v_i ≤ 10^{18}) — the starting number of chips in each pile.

Output

Print a single line containing four integers w_a, w_b, w_f, w_s — the number of games won by Alice, Bob, the first player, the second player, respectively. 

Examples

Input

2 2
4 5


Output

1 1 1 1


Input

2 20
4 5


Output

82 82 6 230

Note

In the first sample, there are a total of four choices for the tuple (a,b).

  * a = b = 1: It does not matter from which pile the chips are removed — there are 9 turns to be made, and the first player also makes the last, and hence he wins.
  * a = b = 2: The second player may win by always selecting the same pile as the first before there are 0 and 1 chips in the piles. Since it is impossible to remove 2 chips from any of them, the first player loses.
  * a = 1 and b = 2: 
    * Suppose Alice starts. She can win by removing a single chip from the pile with 5 chips and then copying Bob's decision. After the next four turns, the game ends with 1 chip in each pile and Bob unable to make a move. 
    * Suppose Bob starts. If he removes two chips from second pile, Alice counters by removing a chip from the first pile. From then on, she can always copy Bob's decision and win. If Bob removes two chips from the first pile in his first turn, Alice can also remove one. As the first pile only has one chip left, Bob is forced to remove two chips from the second pile, leaving 3. Regardless of what Alice does, she wins. 
Hence, Alice wins no matter who starts.
  * a = 2 and b = 1: This is symmetric with the previous case — hence Bob always wins. 



In the second sample, a lot of games, e.g. a = 7 and b = 6, end without anybody being able to remove single chip — which counts as a win for the second player. The games won for the first player are (1, 1), (1, 4), (2, 3), (3, 2), (4, 1), and (5, 5).

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long INFLL = 1e18 + 1;
const int MAX = 200001;
const long long MOD = 1000000007;
const int SZ = 300100;
const double PI = 3.14159265358979323846264338327;
long long inq(long long k, long long q, long long mod) {
  if (q == 0) return 1;
  long long l = inq(k, q / 2, mod);
  if (q % 2 == 0)
    return l * l % mod;
  else
    return l * l % mod * k % mod;
}
long long gcd(long long a, long long b) {
  if (a < b) swap(a, b);
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long cubr(long long a) {
  long long l = -1, r = 1e6 + 2;
  while (l < r - 1) {
    long long mid = (l + r) / 2;
    if (mid * mid * mid > a)
      r = mid;
    else
      l = mid;
  }
  return l;
}
long long max(long long a, long long b) {
  if (a > b) return a;
  return b;
}
long long min(long long a, long long b) { return -1 * max(-a, -b); }
long long possible(long long q) {
  if (q == INF) return -1;
  return q;
}
bool correct(int x, int xx) {
  if (x < 0) return 0;
  if (x >= xx) return 0;
  return 1;
}
long long dsumm(long long x, long long k) {
  long long y = 1;
  long long z = 0;
  for (int i = 0; y < 1e18; i++) {
    z += x / y % k;
    y *= k;
  }
  return z;
}
long long dcount(long long x) {
  long long y = 1;
  long long z = 0;
  int c[100];
  for (int i = 0; i < 10; i++) c[i] = 0;
  for (int i = 0; x > 0; i++) {
    if (c[x / y % 10] == 0) z++;
    c[x / y % 10] = 1;
    x /= 10;
  }
  return z;
}
long long lg10(long long x) {
  if (10000 <= x && x < 100000) return 5;
  if (x == 0) return 0;
  return lg10(x / 10) + 1;
}
long long g(long long x, long long mod) {
  if (x == 0) return 0;
  return x / mod + g(x / mod, mod);
}
bool is_digit(char c) { return ('0' <= c && c <= '9'); }
long long n, m;
long long t[500];
long long v[500];
long long cnt[5];
long long A, B, F, S;
struct change {
  int f;
  int t;
  int x;
};
change C[506];
long long cnt_;
bool comp(change A, change B) { return A.x < B.x; }
long long solve(int a, int b) {
  if (a < b) {
    long long t1 = 0, t2 = 0, t3 = 0, t4 = 0;
    for (int i = 0; i < n; i++) {
      if (0 <= v[i] && v[i] < a) t1++;
      if (a <= v[i] && v[i] < b) t2++;
      if (b <= v[i] && v[i] < 2 * a) t3++;
    }
    t4 = n - t1 - t2 - t3;
    cnt[1] = t1;
    cnt[2] = t2;
    cnt[3] = t3;
    cnt[4] = t4;
    if (t2 > 0 || t4 > 1) {
      return 0;
    } else if ((t3 + t4) % 2 == 0) {
      return 2;
    } else {
      return 1;
    }
  }
  return 4;
}
long long solve2() {
  if (cnt[2] > 0 || cnt[4] > 1) {
    return 0;
  }
  if (cnt[4] == 1 && cnt[3] % 2 == 1) return 0;
  if ((cnt[3] + cnt[4]) % 2 == 0) return 2;
  return 1;
}
void use_change(int i) {
  cnt[C[i].f]--;
  cnt[C[i].t]++;
}
long long tp(int summ, int val, int a) {
  int b = summ - a;
  if (0 <= val && val < a) return 1;
  if (a <= val && val < b) return 2;
  if (b <= val && val < 2 * a) return 3;
  return 4;
}
long long findA[50];
long long cnst;
void predict_changes(int summ, int val) {
  long long now = tp(summ, val, max(summ - m, 1));
  int a;
  cnst = 0;
  findA[cnst] = val + 1;
  cnst++;
  findA[cnst] = summ - val + 0;
  cnst++;
  findA[cnst] = val / 2 + 1;
  cnst++;
  sort(findA, findA + cnst);
  for (int i = 0; i < cnst; i++) {
    a = findA[i];
    if (a < max(1, summ - m) || a > summ / 2 + summ % 2) continue;
    if (tp(summ, val, a) != now) {
      change CC;
      CC.f = now;
      CC.t = tp(summ, val, a);
      CC.x = a;
      C[cnt_] = CC;
      cnt_++;
      now = tp(summ, val, a);
    }
  }
  a = summ / 2 + summ % 2;
  change CC;
  CC.f = now;
  CC.t = 0;
  CC.x = a;
  C[cnt_] = CC;
  cnt_++;
  return;
}
void predict_changes(int summ) {
  for (int i = 0; i < n; i++) {
    predict_changes(summ, v[i]);
  }
  sort(C, C + cnt_, comp);
}
void work(int summ) {
  cnt_ = 0;
  for (int i = 0; i < n; i++) {
    v[i] = t[i] % summ;
  }
  if (summ % 2 == 0) {
    long long g = 0;
    for (int i = 0; i < n; i++) {
      g += v[i] / (summ / 2);
    }
    if (g % 2 == 0) {
      S++;
    } else {
      F++;
    }
  }
  int a = max(1, summ - m);
  if (a >= summ / 2 + summ % 2) return;
  long long last = solve(a, summ - a);
  long long fixed_to = a;
  predict_changes(summ);
  for (int i = 0; i < cnt_; i++) {
    if (solve2() == 0) {
      A += C[i].x - fixed_to;
      B += C[i].x - fixed_to;
    }
    if (solve2() == 1) {
      F += 2 * (C[i].x - fixed_to);
    }
    if (solve2() == 2) {
      S += 2 * (C[i].x - fixed_to);
    }
    use_change(i);
    fixed_to = C[i].x;
    if (cnt[1] + cnt[2] + cnt[3] + cnt[4] != n) {
      break;
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int(i) = 0; (i) != (n); i++) cin >> t[i];
  for (int j = 2; j <= 2 * m; j++) {
    work(j);
  }
  cout << A << " " << B << " " << F << " " << S << endl;
  return 0;
}