#include <bits/stdc++.h>   using namespace std;   const int N = 55, mod = 1LL * 1000 * 1000 * 1000 + 7;   int dp[N][N][2], ans[N][N][2], n, cnt50, cnt100, W, c[N][N], seen[N][N];   bool vis[N][N][2], vis2[N][N][2];   int C(int r, int n) {     if (r == 0 || r == n) return 1;     if (r > n) return 0;     if (seen[r][n]) return c[r][n];     seen[r][n] = true;     return c[r][n] = (C(r - 1, n - 1) + C(r, n - 1)) % mod;   }   int dfs(int x, int y, int tp) {     if (vis2[x][y][tp]) return ans[x][y][tp];     vis2[x][y][tp] = true;     if (tp) {       for (int i = 0; i <= cnt50 - x; i++)         for (int j = 0; j <= cnt100 - y; j++)           if (i * 50 + j * 100 <= W && (i || j) &&               dp[x][y][tp] == dp[x + i][y + j][!tp] + 1)             (ans[x][y][tp] += 1LL * dfs(x + i, y + j, !tp) * C(i, cnt50 - x) %                               mod * C(j, cnt100 - y) % mod) %= mod;     } else {       for (int i = 0; i <= x; i++)         for (int j = 0; j <= y; j++)           if ((i || j) && i * 50 + j * 100 <= W &&               dp[x][y][tp] == dp[x - i][y - j][!tp] + 1)             (ans[x][y][tp] +=              1LL * dfs(x - i, y - j, !tp) * C(i, x) % mod * C(j, y) % mod) %= mod;     }     return ans[x][y][tp];   }   struct Node {     int x = 0, y = 0, tp = 0;     Node(int a = 0, int b = 0, int c = 0) { x = a, y = b, tp = c; }   };   int main() {     ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);     for (int i = 0; i < N; i++)       for (int j = 0; j < N; j++)         for (int k = 0; k < 2; k++) dp[i][j][k] = 1 << 29;     cin >> n >> W;     for (int i = 0, a; i < n; i++) {       cin >> a;       cnt50 += (a == 50);       cnt100 += (a == 100);     }     dp[0][0][0] = dp[0][0][1] = 0;     vis[0][0][0] = vis[0][0][1] = true;     ans[0][0][0] = ans[0][0][1] = 1;     queue<Node> q;     q.push(Node(0, 0, 0)), q.push(Node(0, 0, 1));     while (q.size()) {       Node tmp = q.front();       q.pop();       int x = tmp.x, y = tmp.y, tp = tmp.tp;       if (tp) {         for (int i = 0; i <= cnt50 - x; i++)           for (int j = 0; j <= cnt100 - y; j++)             if (i * 50 + j * 100 <= W && (i || j) && !vis[x + i][y + j][!tp]) {               q.push(Node(x + i, y + j, !tp));               dp[x + i][y + j][!tp] = dp[x][y][tp] + 1;               vis[x + i][y + j][!tp] = true;             }       } else {         for (int i = 0; i <= x; i++)           for (int j = 0; j <= y; j++)             if ((i || j) && i * 50 + 100 * j <= W && !vis[x - i][y - j][!tp]) {               q.push(Node(x - i, y - j, !tp));               dp[x - i][y - j][!tp] = dp[x][y][tp] + 1;               vis[x - i][y - j][!tp] = true;             }       }     }     dfs(cnt50, cnt100, 0);     if (dp[cnt50][cnt100][0] >= (1 << 29)) dp[cnt50][cnt100][0] = -1;     cout << dp[cnt50][cnt100][0] <<   n  << ans[cnt50][cnt100][0] <<   n ;     return 0;   }   