#include <bits/stdc++.h>
using namespace std;
long long int fato[120];
pair<long long int, long long int> mdc(long long int a, long long int b) {
  if (b == 0) return pair<long long int, long long int>(1, 0);
  pair<long long int, long long int> u = mdc(b, a % b);
  return pair<long long int, long long int>(u.second,
                                            u.first - (a / b) * u.second);
}
long long int invmod(long long int a, long long int M = 1000000007LL) {
  pair<long long int, long long int> r = mdc(a, M);
  if (r.first * a + r.second * M == 1) return (r.first + M) % M;
  return 0;
}
long long int fat(long long int n, long long int M = 1000000007LL) {
  if (n == 0 || n == 1) return 1;
  if (fato[n] != -1) return fato[n];
  return fato[n] = (n * fat(n - 1)) % M;
}
long long int binomial(long long int n, long long int k,
                       long long int M = 1000000007LL) {
  long long int a = fat(n) * invmod(fat(k), M);
  long long int b = invmod(fat(n - k), M);
  return ((a % M) * b) % M;
}
int n, k, n50, n100;
int dist[51][51][2];
class Elemento {
 public:
  int n50, n100, ind;
  Elemento(int n50, int n100, int ind) : n50(n50), n100(n100), ind(ind) {}
};
vector<Elemento> pai[51][51][2];
long long int memo[51][51][2];
long long int calcula(int a, int b, int ind) {
  if (a == n50 && b == n100 && ind == 0) return 1;
  if (memo[a][b][ind] != -1) return memo[a][b][ind];
  int c, d, ot;
  long long int res = 0;
  for (int k = 0; k < ((int)pai[a][b][ind].size()); k++) {
    c = pai[a][b][ind][k].n50;
    d = pai[a][b][ind][k].n100;
    ot = pai[a][b][ind][k].ind;
    int ra, rb;
    ra = n50 - c;
    rb = n100 - d;
    long long int x =
        (binomial(c, a - ra) * binomial(d, b - rb)) % 1000000007LL;
    x = (x * calcula(c, d, ot)) % 1000000007LL;
    res = (res + x) % 1000000007LL;
  }
  return memo[a][b][ind] = res;
}
void dijkstra() {
  queue<Elemento> q;
  memset(dist, 0x3f3f3f3f, sizeof(dist));
  dist[n50][n100][0] = 0;
  q.push(Elemento(n50, n100, 0));
  while (!q.empty()) {
    int a, b, ind;
    a = q.front().n50;
    b = q.front().n100;
    ind = q.front().ind;
    q.pop();
    if (a == n50 && b == n100 && ind == 1) break;
    int ra, rb, ot;
    ra = n50 - a;
    rb = n100 - b;
    ot = (ind + 1) % 2;
    for (int i = 0; i <= a; i++) {
      for (int j = 0; j <= b; j++) {
        if (i == 0 && j == 0) continue;
        if (i * 50 + j * 100 <= k) {
          int c, d;
          c = ra + i;
          d = rb + j;
          if (dist[c][d][ot] < dist[a][b][ind] + 1) continue;
          if (dist[c][d][ot] == dist[a][b][ind] + 1) {
            pai[c][d][ot].push_back(Elemento(a, b, ind));
          } else {
            dist[c][d][ot] = dist[a][b][ind] + 1;
            pai[c][d][ot].clear();
            pai[c][d][ot].push_back(Elemento(a, b, ind));
            q.push(Elemento(c, d, ot));
          }
        }
      }
    }
  }
  int d = dist[n50][n100][1];
  if (d == 0x3f3f3f3f) {
    printf("-1\n0\n");
    return;
  }
  printf("%d\n", d);
  memset(memo, -1, sizeof(memo));
  long long int res = calcula(n50, n100, 1);
  cout << res << endl;
}
int main() {
  scanf("%d %d", &n, &k);
  n50 = 0;
  n100 = 0;
  memset(fato, -1, sizeof(fato));
  for (int i = 0; i < (n); i++) {
    int x;
    scanf("%d", &x);
    if (x == 50)
      n50++;
    else
      n100++;
  }
  dijkstra();
  return 0;
}
