#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:64000000")
const int toMod = 1000000007;
const int MAXN = 52;
struct state {
  int c1;
  int c2;
  int dir;
  pair<int, int> res;
  void init(int C1, int C2, int DIR) {
    c1 = C1;
    c2 = C2;
    dir = DIR;
  }
  bool operator<(const state &B) const {
    if (res.first == -2) return true;
    if (B.res.first == -2) return false;
    return res > B.res;
  }
};
int n, m;
pair<int, int> f[MAXN][MAXN][2];
int cnt1, cnt2;
long long C[MAXN][MAXN];
priority_queue<state> q;
inline void init() {
  cnt1 = cnt2 = 0;
  scanf("%d%d", &n, &m);
  m /= 50;
  int x;
  for (int i = 0; i < n; ++i) {
    scanf("%d", &x);
    if (x == 50)
      ++cnt1;
    else
      ++cnt2;
  }
}
void run(int c1, int c2, int dir) {
  if (!dir) {
    int lm1 = min(m, c1);
    for (int i1 = lm1; i1 >= 0; --i1) {
      int lm2 = min((m - i1) >> 1, c2);
      for (int i2 = lm2; i2 >= 0; --i2) {
        if (!i1 && !i2) continue;
        int nc1 = c1 - i1;
        int nc2 = c2 - i2;
        if (f[nc1][nc2][1].first == -1 ||
            f[nc1][nc2][1].first > f[c1][c2][0].first + 1) {
          f[nc1][nc2][1].first = f[c1][c2][0].first + 1;
          f[nc1][nc2][1].second = 0;
        }
        if (f[nc1][nc2][1].first == f[c1][c2][0].first + 1) {
          long long cur = f[c1][c2][0].second;
          cur *= C[c1][i1];
          cur %= toMod;
          cur *= C[c2][i2];
          cur %= toMod;
          f[nc1][nc2][1].second += (int)cur;
          if (f[nc1][nc2][1].second >= toMod) f[nc1][nc2][1].second -= toMod;
          state ST;
          ST.init(nc1, nc2, 1);
          ST.res = f[nc1][nc2][1];
          q.push(ST);
        }
      }
    }
  } else {
    int lm1 = min(m, cnt1 - c1);
    for (int i1 = 0; i1 <= lm1; ++i1) {
      int lm2 = min((m - i1) >> 1, cnt2 - c2);
      for (int i2 = 0; i2 <= lm2; ++i2) {
        if (!i1 && !i2) continue;
        int nc1 = c1 + i1;
        int nc2 = c2 + i2;
        if (f[nc1][nc2][0].first == -1 ||
            f[nc1][nc2][0].first > f[c1][c2][1].first + 1) {
          f[nc1][nc2][0].first = f[c1][c2][1].first + 1;
          f[nc1][nc2][0].second = 0;
        }
        if (f[nc1][nc2][0].first == f[c1][c2][1].first + 1) {
          long long cur = f[c1][c2][1].second;
          cur *= C[cnt1 - c1][i1];
          cur %= toMod;
          cur *= C[cnt2 - c2][i2];
          cur %= toMod;
          f[nc1][nc2][0].second += (int)cur;
          if (f[nc1][nc2][0].second >= toMod) f[nc1][nc2][0].second -= toMod;
          state ST;
          ST.init(nc1, nc2, 0);
          ST.res = f[nc1][nc2][0];
          q.push(ST);
        }
      }
    }
  }
}
int main() {
  init();
  if (!m) {
    printf("-1\n");
    printf("0\n");
    return 0;
  }
  memset(C, 0, sizeof C);
  C[0][0] = 1;
  for (int i = 1; i < MAXN; ++i) {
    C[i][0] = 1;
    for (int j = 1; j <= i; ++j) {
      C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % toMod;
    }
  }
  memset(f, -1, sizeof f);
  f[cnt1][cnt2][0] = pair<int, int>(0, 1);
  state ST;
  ST.init(cnt1, cnt2, 0);
  ST.res = f[cnt1][cnt2][0];
  q.push(ST);
  while (!q.empty()) {
    state cur = q.top();
    q.pop();
    int c1 = cur.c1;
    int c2 = cur.c2;
    int dir = cur.dir;
    if (cur.res != f[c1][c2][dir]) continue;
    run(c1, c2, dir);
  }
  pair<int, int> res = f[0][0][1];
  if (res.first == -1) {
    res.first = -1;
    res.second = 0;
  }
  printf("%d\n", res.first);
  printf("%d\n", res.second);
  return 0;
}
