import java.util.*;
public class c {
	static long mod = (long)1e9+7;
	static int small, big;
public static void main(String[] args)
{
	int[][] cs = comb(101);
	Scanner input = new Scanner(System.in);
	int n = input.nextInt(), k = input.nextInt();
	small = big = 0;
	for(int i = 0; i<n; i++)
	{
		if(input.nextInt() == 50) small++;
		else big++;
	}
	int[][][] ds = new int[2][small+1][big+1];
	for(int[][] A : ds)
		for(int[] B : A)
			Arrays.fill(B, 987654321);
	long[][][] ways = new long[2][small+1][big+1];
	ds[0][small][big] = 0;
	ways[0][small][big] = 1;
	Queue<Integer> q = new LinkedList<Integer>();
	q.add(0);
	q.add(small);
	q.add(big);
	while(!q.isEmpty())
	{
		int side = q.poll();
		int a = q.poll();
		int b = q.poll();
		int d = ds[side][a][b];
		long w = ways[side][a][b];
		int maxa = a, maxb = b;
		if(side == 1)
		{
			maxa = small - a;
			maxb = big - b;
		}
		for(int i = 0; i<=maxa; i++)
			for(int j = 0; j<=maxb; j++)
			{
				if(i*50 +  j*100 > k) break;
				if(i == 0 && j == 0) continue;
				int ns = 1 - side;
				int na = a + i * (side == 1 ? 1 : -1);
				int nb = b + j * (side == 1 ? 1 : -1);
				long edgeWays = ((long)cs[maxa][i] * cs[maxb][j])%mod;
				//System.out.println(side+" "+a+" "+b+" "+ns+" "+na+" "+nb);
				if(1+d < ds[ns][na][nb])
				{
					ds[ns][na][nb] = 1 + d;
					ways[ns][na][nb] = (w * edgeWays)%mod;
					q.add(ns);
					q.add(na);
					q.add(nb);
				}
				else if(1+d == ds[ns][na][nb])
				{
					ways[ns][na][nb] += (w*edgeWays)%mod;
					if(ways[ns][na][nb] >= mod) ways[ns][na][nb] -= mod;
				}
			}
	}
	if(ds[1][0][0] > 1e8)
		ds[1][0][0] = -1;
	System.out.println(ds[1][0][0]);
	System.out.println(ways[1][0][0]);

}
public static int[][] comb(int n)
{
	int[][] comb = new int[n+1][n+1];
	for(int i = 0; i<= n; i++)
		comb[i][0] = 1;
	for(int i = 1; i<= n; i++)
		for(int j = 1; j<= i; j++)
			comb[i][j] = (comb[i-1][j] + comb[i-1][j-1])%(int)(mod);
	return comb;
}
}


//package a2oj;
import java.util.*;

public class GregAndFriends {
	static int n, k, a = 0, b = 0;
	static long MOD = 1000000007, ans = 0;
	static long[][] choose = new long[100][100];
	static LinkedList<Integer> q = new LinkedList<Integer>();
	static HashMap<Integer, Pair> ways = new HashMap<Integer, Pair>();
	static class Pair {
		int d;
		long w;
		public Pair(int D, long W) {
			d = D;
			w = W;
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		k = sc.nextInt();
		for(int i = 0; i < n; i++)
			if(sc.nextInt() == 50)
				a++;
			else
				b++;
		sc.close();
		fillChoose();
		int startMask = 1000000 + 100 * a + b;
		q.add(startMask);
		ways.put(startMask, new Pair(0, 1));
		while(!q.isEmpty())
			bfs(q.pollFirst());
		System.out.println(ways.containsKey(0) ? ways.get(0).d + "\n" + ways.get(0).w : "-1\n0");
	}
	static void bfs(int mask) {
		int boat = mask / 1000000;
		int nA = (mask % 1000000) / 100, nB = mask % 100;
		if(boat > 0) {
			for(int i = nA; i >= 0 && 50 * (nA - i) <= k; i--)
				for(int j = nB; j >= 0 && 50 * (nA - i) + 100 * (nB - j) <= k; j--)
					if(i != nA || j != nB)
						resolve(i, j, boat, mask, choose[nA][i] * choose[nB][j] % MOD);
		} else {
			for(int i = nA; i <= a && 50 * (i - nA) <= k; i++)
				for(int j = nB; j <= b && 50 * (i - nA) + 100 * (j - nB) <= k; j++)
					if(i != nA || j != nB)
						resolve(i, j, boat, mask, choose[a - nA][i - nA] * choose[b - nB][j - nB] % MOD);
		}
	}
	static void resolve(int i, int j, int boat, int mask, long edgeWays) {
		int newMask = 1000000 * (1 - boat) + i * 100 + j;
		int newD = ways.get(mask).d + 1;
		if(!ways.containsKey(newMask)) {
			ways.put(newMask, new Pair(newD, 0));
			q.add(newMask);
		}
		if(ways.get(newMask).d == newD)
			ways.get(newMask).w = (ways.get(newMask).w + ways.get(mask).w * edgeWays % MOD) % MOD;
	}
	static void fillChoose() {
		for(int i = 0; i < 100; i++)
			choose[i][0] = 1;
		for(int i = 1; i < 100; i++)
			for(int j = 1; j <= i; j++)
				choose[i][j] = (choose[i - 1][j - 1] + choose[i - 1][j]) % MOD;
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class C {
	static int mod = 1000000007;

	static class State implements Comparable<State> {
		int fiftyCnt, hundertCnt, where;
		int steps;
		long ways;

		public State(int f, int h, int w, int s, long way) {
			fiftyCnt = f;
			hundertCnt = h;
			where = w;
			steps = s;
			ways = way;
		}

		public int compareTo(State s) {
			return new Integer(steps).compareTo(new Integer(s.steps));
		}
	}

	static long[][] dp;
	static long[][][][] cache;
	static int boatWeight, fiftyCnt, hundretCnt;

	public static long solve(int fifty, int hundert, int where, int rem) {
		if (rem == 0) {
			if (where == 1 && fifty == 0 && hundert == 0) {
				return 1;
			}
			return 0;
		}
		if (cache[fifty][hundert][where][rem] != -1)
			return cache[fifty][hundert][where][rem];
		long res = 0;
		if (where == 0) {
			int maxFifty = boatWeight / 50;
			for (int i = 0; i <= Math.min(maxFifty, fifty); i++) {
				int maxHundret = (boatWeight - i * 50) / 100;
				int fiftyTaken = i;
				for (int j = 0; j <= Math.min(maxHundret, hundert); j++) {
					int hundretTaken = j;
					if (fiftyTaken + hundretTaken == 0)
						continue;
					res = (res + ((((solve(fifty - fiftyTaken, hundert
							- hundretTaken, 1, rem - 1) * combin(fifty,
							fiftyTaken)) % mod) * combin(hundert, hundretTaken)) % mod))
							% mod;
				}
			}
		} else {
			int maxFifty = boatWeight / 50;
			int fiftyHere = fiftyCnt - fifty;
			int hundretHere = hundretCnt - hundert;
			for (int i = 0; i <= Math.min(maxFifty, fiftyHere); i++) {
				int maxHundret = (boatWeight - i * 50) / 100;
				int fiftyTaken = i;
				for (int j = 0; j <= Math.min(maxHundret, hundretHere); j++) {
					int hundretTaken = j;
					if (fiftyTaken + hundretTaken == 0)
						continue;
					res = (res + ((((solve(fifty + fiftyTaken, hundert
							+ hundretTaken, 0, rem - 1) * combin(fiftyHere,
							fiftyTaken)) % mod) * combin(hundretHere,
							hundretTaken)) % mod))
							% mod;
				}
			}
		}
		return cache[fifty][hundert][where][rem] = res;
	}

	public static long combin(int n, int k) {
		if (n < k)
			return 0;
		if (k == 0)
			return 1;
		if (n == k)
			return 1;
		if (dp[n][k] != -1)
			return dp[n][k];
		return dp[n][k] = (combin(n - 1, k) + combin(n - 1, k - 1)) % mod;
	}

	public static void main(String[] args) throws Exception {
		int peopleCnt = nextInt();
		boatWeight = nextInt();
		fiftyCnt = 0;
		hundretCnt = 0;
		for (int i = 0; i < peopleCnt; i++) {
			if (nextInt() == 50) {
				fiftyCnt++;
			} else {
				hundretCnt++;
			}
		}
		dp = new long[Math.max(fiftyCnt, hundretCnt) + 1][Math.max(fiftyCnt,
				hundretCnt) + 1];
		for (int i = 0; i < dp.length; i++) {
			Arrays.fill(dp[i], -1);
		}
		int maxSteps = 1000;
		cache = new long[fiftyCnt + 1][hundretCnt + 1][2][maxSteps + 1];
		for (int i = 0; i <= fiftyCnt; i++) {
			for (int j = 0; j <= hundretCnt; j++) {
				for (int k = 0; k < 2; k++) {
					Arrays.fill(cache[i][j][k], -1);
				}
			}
		}
		for (int i = 1; i <= maxSteps; i++) {
			long tmp = solve(fiftyCnt, hundretCnt, 0, i);
			if (tmp != 0) {
				System.out.println(i);
				System.out.println(tmp);
				return;
			}
		}
		System.out.println(-1);
		System.out.println(0);
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer st = new StringTokenizer("");

	static int nextInt() throws Exception {
		return Integer.parseInt(next());
	}

	static String next() throws Exception {
		while (true) {
			if (st.hasMoreTokens()) {
				return st.nextToken();
			}
			String s = br.readLine();
			if (s == null) {
				return null;
			}
			st = new StringTokenizer(s);
		}
	}
}


import java.util.*;
import java.math.*;
import java.io.*;

import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class  test{

	// ArrayList<Integer> lis = new ArrayList<Integer>();
	// ArrayList<String> lis = new ArrayList<String>();
	//  PriorityQueue<P> que = new PriorityQueue<P>();
	// PriorityQueue<Integer> que = new PriorityQueue<Integer>();
	//  Stack<Integer> que = new Stack<Integer>();
    //	static long sum=0;
	// 1000000007 (10^9+7)
	static int mod = 1000000007;
	//static int mod = 1000000009,r=0;
   // static int dx[]={1,-1,0,0};
//	static int dy[]={0,0,1,-1};
//	static int dx[]={1,-1,0,0,1,1,-1,-1};
//  static int dy[]={0,0,1,-1,1,-1,1,-1};
	//static long H,L;
	//static Set<Integer> set = new HashSet<Integer>();

public  static void main(String[] args)   throws Exception, IOException{
   //String line=""; throws Exception, IOException
   //(line=br.readLine())!=null
	//Scanner sc =new Scanner(System.in);
	// !!caution!! int long //
	Reader sc = new Reader(System.in);
  // while( ){
	  // int  n=sc.nextInt(),m=sc.nextInt();//a[]=new int[n],b[]=new int[n];
	int   n=sc.nextInt(),k=sc.nextInt();
	//int x[]=new int[n];
	int f=0,h=0,c=0;

	for(int i=0;i<n;i++){
        int a=sc.nextInt();
		if( a==50 )f++;else h++;
	}
	long b[][][]=new long[2][f+1][h+1];
	//for(int i=0;i<=f;i++)for(int t=0;t<=h;t++)b[0][i][t][0]=b[1][i][t][0]=1000;
    b[0][f][h]++;
	while(true){

	 for(int i=0;i<=f;i++)for(int t=0;t<=h;t++){

		 if( b[c%2][i][t]<1  )continue;
		// db(c,i,t);
		 for(int w=0;w<=i;w++)for(int q=0;q<=t;q++){
			 if( k<w*50+q*100 )continue;
			 if( w==0 && q==0 )continue;
			 b[(c+1)%2][w+f-i][q+h-t]+= (b[c%2][i][t]*(com(i,w)*com(t,q))%mod)%mod ;
			 b[(c+1)%2][w+f-i][q+h-t]%=mod;
		 }

	 }
	 for(int i=0;i<=f;i++)for(int t=0;t<=h;t++)b[c%2][i][t]=0;
	 c++;
	 db(c);
	 if(0<b[1][f][h])break;
	 if( 210<c )break;
	}

	System.out.println(b[1][f][h]==0? -1:c);
	System.out.println(b[1][f][h]);

	//System.out.println();

}

static void db(Object... os){
    System.err.println(Arrays.deepToString(os));

}

static long com( int n, int m ) {//beware! n<m
    if( n < m || m < 0 ) {
        throw new IllegalArgumentException( "invalid parameter ( n : " + n + ", m : " + m + ")" );
    }
    long c = 1;
    m = ( n - m < m ? n - m : m );
    for( int ns = n - m + 1, ms = 1; ms <= m; ns ++, ms ++ ) {
        c *= ns;
        c /= ms;
    }
    return c;
}

}

class Reader
{
	private BufferedReader x;
	private StringTokenizer st;

	public Reader(InputStream in)
	{
		x = new BufferedReader(new InputStreamReader(in));
		st = null;
	}
	public String nextString() throws IOException
	{
		while( st==null || !st.hasMoreTokens() )
			st = new StringTokenizer(x.readLine());
		return st.nextToken();
	}
	public int nextInt() throws IOException
	{
		return Integer.parseInt(nextString());
	}
	public long nextLong() throws IOException
	{
		return Long.parseLong(nextString());
	}
	public double nextDouble() throws IOException
	{
		return Double.parseDouble(nextString());
	}
}

class P  {
	int x,y,z,c;
	long a;
	P(int x,int y,int z,int c,long a){this.c=c; this.a=a; this.x=x; this.y=y;this.z=z;  }

}
//*/


import java.io.*;
import java.util.*;

public class C implements Runnable{
	public static void main (String[] args) {new Thread(null, new C(), "_cf", 1 << 28).start();}

	int[] fact;
	int n50, n100;
	int n, k, MOD = (int)1e9+7, oo = (int)2e9;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		fact = new int[100];
		fact[0] = fact[1] = 1;
		for(int i = 2; i < fact.length; i++)
			fact[i] = mult(fact[i-1], i);
		int[][] nCk = new int[100][100];
		for(int i = 0; i < nCk.length; i++) {
			for(int j = 0; j <= i; j++) {
				nCk[i][j] = nCk(i, j);
			}
		}

		n = fs.nextInt();
		k = fs.nextInt();
		int n50 = 0, n100 = 0;
		for(int i = 0; i < n; i++) {
			int x = fs.nextInt();
			if(x == 50) n50++;
			else n100++;
		}
		this.n50 = n50;
		this.n100 = n100;

		int[][][] dist = new int[2][n50+1][n100+1];
		int[][][] ways = new int[2][n50+1][n100+1];
		for(int[][] d : dist)
			for(int[] dd : d)
				Arrays.fill(dd, oo);
		dist[0][n50][n100] = 0;
		ways[0][n50][n100] = 1;
		ArrayDeque<Node> bfs = new ArrayDeque<>();
		bfs.add(new Node(n50, n100, 0, 0));
		while(!bfs.isEmpty()) {
			Node now = bfs.pollFirst();
//			System.out.println(now);
			int nn50 = n50 - now.n50;
			int nn100 = n100 - now.n100;
			for(int i = 0; i <= now.n50; i++) {
				for(int j = 0; j <= now.n100; j++) {
					if(i + j == 0) continue;
					if(i*50 + j*100 > k) continue;
					int ndist = 1 + dist[now.side][now.n50][now.n100];
					int x = dist[now.side^1][nn50+i][nn100+j];
					int tf = mult(ways[now.side][now.n50][now.n100], mult(nCk[now.n50][i], nCk[now.n100][j]));

					if(x > ndist) {
						dist[now.side^1][nn50+i][nn100+j] = ndist;
						ways[now.side^1][nn50+i][nn100+j] = tf;
						bfs.add(new Node(nn50+i, nn100+j, now.side^1, ndist));
					}
					else if(x == ndist) {
						ways[now.side^1][nn50+i][nn100+j] = add(ways[now.side^1][nn50+i][nn100+j], tf);
					}
				}
			}
		}

		int res = dist[1][n50][n100];
		int way = ways[1][n50][n100];
		if(res == oo) { res = -1; way = 0; }
		out.printf("%d\n%d\n", res, way);

		out.close();
	}

	int add(long a, long b) {
		a %= MOD;
		b %= MOD;
		a += b;
		a %= MOD;
		return (int)a;
	}

	int nCk(int n, int k) {
		int num = fact[n];
		int den = mult(fact[k], fact[n-k]);
		int inv = inv(den);
		return mult(num, inv);
	}

	int inv(long x) {
		long res = power(x, MOD - 2, MOD);
		while(res < 0) res += MOD;
		return (int)res;
	}

	int mult(long a, long b) {
		a %= MOD;
		b %= MOD;
		a *= b;
		a %= MOD;
		return (int)a;
	}

	long power (long x, long y, long m) {
		long res = 1;
		x %= m;
		while(y > 0) {
			if(y % 2 == 1) {
				res = (res * x) % m;
			}
			y >>= 1L;
						x = (x * x) % m;
		}
		return res;
	}

	class Node implements Comparable<Node> {
		int n50, n100, side, dist;
		Node(int a, int b, int c, int d) {
			n50 = a; n100 = b;
			side = c; dist = d;
		}
		public String toString() {
			return String.format("(%d, %d) %d %d", n50, n100, side, dist);
		}
		public int compareTo(Node n) {
			return Integer.compare(dist, n.dist);
		}
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


// Problem : C. Greg and Friends
// Contest : Codeforces - Codeforces Round #179 (Div. 1)
// URL : https://codeforces.com/contest/295/problem/C
// Memory Limit : 256 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

import java.io.*;
import java.util.*;
import java.util.stream.*;

public class a implements Runnable{

    public static void main(String[] args) {
        new Thread(null, new a(), "process", 1<<26).start();
    }
	public void run() {
		FastReader scan = new FastReader();
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		//PrintWriter out = new PrintWriter("file.out");
		Task solver = new Task();
		//int t = scan.nextInt();
		int t = 1;
		for(int i = 1; i <= t; i++) solver.solve(i, scan, out);
		out.close();
	}

	static class Task {
		static final int inf = Integer.MAX_VALUE;

		public void solve(int testNumber, FastReader sc, PrintWriter pw) {
			//CHECK FOR QUICKSORT TLE
			//***********************//
			//CHECK FOR INT OVERFLOW
			//***********************//
			int n = sc.nextInt();
			int we = sc.nextInt() / 50;
			int[] ppl = new int[n];
			int a = 0;
			int b = 0;
			int mod = 1000000007;
			for(int i = 0; i < n; i++) {
				ppl[i] = sc.nextInt() / 50;
				a += ppl[i] & 1;
				b += ppl[i] / 2;
			}
			long[][] choose = new long[52][52];
			for(int i = 1; i <= 50; i++) {
				for(int j = 0; j <= i; j++) {
					choose[i][j] = choose_mod_one(i, j, mod);
				}
			}
			long[][][] dp = new long[200][52][52];
			dp[0][0][0] = 1;
			choose[0][0] = 1;
			for(int i = 1; i < 200; i ++) {
				for(int j = 0; j <= a; j++) {
					for(int k = 0; k <= b; k++) {
						if((i & 1) == 1) {
							for(int l = 0; l <= j; l++) {
								for(int m = 0; m <= k; m++) {
									if(l == j && m == k) continue;
									int num1s = j - l;
									int num2s = k - m;
									int left1s = a - l;
									int left2s = b - m;
									if(num1s * 1 + num2s * 2 > we) continue;
									dp[i][j][k] += dp[i - 1][l][m] * choose[left1s][num1s] % mod *
										choose[left2s][num2s] % mod;
									dp[i][j][k] %= mod;
								}
							}
						}
						else {
							for(int l = j; l <= a; l++) {
								for(int m = k; m <= b; m++) {
									if(l == j && m == k) continue;
									int num1s = l - j;
									int num2s = m - k;
									int left1s = l;
									int left2s = m;
									if(num1s * 1 + num2s * 2 > we) continue;
									dp[i][j][k] += dp[i - 1][l][m] * choose[left1s][num1s] % mod *
										choose[left2s][num2s] % mod;
									dp[i][j][k] %= mod;
								}
							}
						}
					}
				}
				if(dp[i][a][b] > 0) break;
			}
			for(int i = 0; i < 200; i++) {
				if(dp[i][a][b] > 0) {
					pw.println(i);
					pw.println(dp[i][a][b]);
					return;
				}
			}
			pw.println(-1);
			pw.println(0);
		}
		long choose_mod_one(long n, long k, long p)
		{
		    // For small k, no recursion is necessary
		    if (k < p) return choose_mod_two(n,k,p);
		    long q_n, r_n, q_k, r_k, choose;
		    q_n = n / p;
		    r_n = n % p;
		    q_k = k / p;
		    r_k = k % p;
		    choose = choose_mod_two(r_n, r_k, p);
		    choose *= choose_mod_one(q_n, q_k, p);
		    return choose % p;
		}

		// Preconditions: 0 <= k <= min(n,p-1); p > 1 prime
		long choose_mod_two(long n, long k, long p)
		{
		    n %= p;
		    if (n < k) return 0;
		    if (k == 0 || k == n) return 1;
		    if (k > n/2) k = n-k;
		    long num = n, den = 1;
		    for(n = n-1; k > 1; --n, --k)
		    {
		        num = (num * n) % p;
		        den = (den * k) % p;
		    }
		    den = invert_mod(den,p);
		    return (num * den) % p;
		}
		long invert_mod(long k, long m)
		{
		    if (m == 0) return (k == 1 || k == -1) ? k : 0;
		    if (m < 0) m = -m;
		    k %= m;
		    if (k < 0) k += m;
		    boolean neg = true;
		    long p1 = 1, p2 = 0, k1 = k, m1 = m, q, r, temp;
		    while(k1 > 0) {
		        q = m1 / k1;
		        r = m1 % k1;
		        temp = q*p1 + p2;
		        p2 = p1;
		        p1 = temp;
		        m1 = k1;
		        k1 = r;
		        neg = !neg;
		    }
		    return neg ? m - p2 : p2;
		}
	}
	static long binpow(long a, long b, long m) {
		a %= m;
		long res = 1;
		while (b > 0) {
			if ((b & 1) == 1)
				res = res * a % m;
			a = a * a % m;
			b >>= 1;
		}
		return res;
	}
	static void sort(int[] x){
		shuffle(x);
		Arrays.sort(x);
	}
	static void sort(long[] x){
		shuffle(x);
		Arrays.sort(x);
	}
	static class tup implements Comparable<tup>{
		int a, b;
		tup(int a,int b){
			this.a=a;
			this.b=b;
		}
		@Override
		public int compareTo(tup o){
			return Integer.compare(o.b,b);
		}
	}
	static void shuffle(int[] a) {
		Random get = new Random();
		for (int i = 0; i < a.length; i++) {
			int r = get.nextInt(i + 1);
			int temp = a[i];
			a[i] = a[r];
			a[r] = temp;
		}
	}

	static void shuffle(long[] a) {
		Random get = new Random();
		for (int i = 0; i < a.length; i++) {
			int r = get.nextInt(i + 1);
			long temp = a[i];
			a[i] = a[r];
			a[r] = temp;
		}
	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public FastReader(String s) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(new File(s)));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}

}


import java.util.*;

public class C {
	private static Scanner in;

	final static int M = 1000000007;

	public void run() {
		int n = in.nextInt();
		int k = in.nextInt() / 50;
		int small = 0;
		for (int i = 0; i < n; i++) {
			if (in.nextInt() == 50) {
				small++;
			}
		}
		if (small == 0) {
			small = n;
			k /= 2;
		}
		int[][] cnk = new int[n + 1][n + 1];
		for (int i = 0; i <= n; i++) {
			cnk[i][i] = cnk[i][0] = 1;
			for (int j = 1; j < i; j++) {
				cnk[i][j] = (cnk[i - 1][j - 1] + cnk[i - 1][j]) % M;
			}
		}
		int[][] a = new int[n + 1][n + 1];
		boolean[][] aa = new boolean[n + 1][n + 1];
		a[n][small] = 1;
		aa[n][small] = true;
		for (int t = 0;; t++) {
			int[][] b = new int[n + 1][n + 1];
			boolean[][] bb = new boolean[n + 1][n + 1];
			for (int m = 0; m <= n; m++) {
				for (int s = 0; s <= m; s++) {
					if (!aa[m][s]) {
						continue;
					}
					int h = m - s;
					int mm = n - m;
					int ss = small - s;
					for (int i = 0; i <= s; i++) {
						for (int j = 0; j <= h; j++) {
							if (i + 2 * j > k) {
								break;
							}
							if (i + j == 0) {
								continue;
							}
							long w = a[m][s];
							w = (w * cnk[s][i]) % M;
							w = (w * cnk[h][j]) % M;
							b[mm + i + j][ss + i] = (int) ((b[mm + i + j][ss + i] + w) % M);
							bb[mm + i + j][ss + i] = true;
						}
					}
				}
			}
			a = b;
			aa = bb;
			if ((t % 2 == 0) && (aa[n][small])) {
				System.out.println(t + 1);
				System.out.println(a[n][small]);
				return;
			}
			if (k < 3 && t > 5 * n) {
				System.out.println("-1\n0");
				return;
			}
		}
	}

	public static void main(String[] args) {
		Locale.setDefault(Locale.US);
		in = new Scanner(System.in);
		new C().run();
		in.close();
	}
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;
import static java.lang.Math.*;

/* spar5h */

public class cf1 implements Runnable {

	final long mod = (long)1e9 + 7;

	long modExp(long x, long y) {

		if(y == 0)
			return 1;

		if(y == 1)
			return x;

		long ret = modExp(x, y / 2);

		ret = ret * ret % mod;

		if(y % 2 == 1)
			ret = ret * x % mod;

		return ret;
	}

	long[] fact, invFact;

	long nCr(int n, int r) {
		return fact[n] * invFact[r] % mod * invFact[n - r] % mod;
	}

	public void run() {

		InputReader s = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);

		fact = new long[50 + 1]; fact[0] = 1;
		invFact = new long[50 + 1]; invFact[0] = 1;

		for(int i = 1; i <= 50; i++) {
			fact[i] = fact[i - 1] * i % mod;
			invFact[i] = invFact[i - 1] * modExp(i, mod - 2) % mod;
		}

		int n = s.nextInt(), k = s.nextInt() / 50;

		int[] f = new int[3];

		for(int i = 0; i < n; i++)
			f[s.nextInt() / 50]++;

		int LIM = 6 * n;

		long[][][] dp = new long[LIM][f[1] + 1][f[2] + 1];

		dp[0][f[1]][f[2]] = 1;

		int res = -1;

		for(int i = 1; i < LIM; i++) {

			if(i % 2 == 1) {
				for(int a = 0; a <= f[1]; a++)
					for(int b = 0; b <= f[2]; b++)
						for(int c = 0; c <= f[1] - a; c++)
							for(int d = 0; d <= f[2] - b; d++)
								if(c + d >= 1 && c + d * 2 <= k)
									dp[i][a][b] = (dp[i][a][b] + dp[i - 1][a + c][b + d] * nCr(a + c, c) % mod * nCr(b + d, d)) % mod;
			}

			else {
				for(int a = 0; a <= f[1]; a++)
					for(int b = 0; b <= f[2]; b++)
						for(int c = 0; c <= a; c++)
							for(int d = 0; d <= b; d++)
								if(c + d >= 1 && c + d * 2 <= k)
									dp[i][a][b] = (dp[i][a][b] + dp[i - 1][a - c][b - d] * nCr(f[1] - (a - c), c) % mod * nCr(f[2] - (b - d), d) % mod) % mod;
			}

			if(dp[i][0][0] > 0) {
				res = i; break;
			}
		}

		w.println(res);

		if(res != -1)
			w.println(dp[res][0][0]);
		else
			w.println(0);

 		w.close();
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {

			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars) {

				curChar = 0;

				try {
					numChars = stream.read(buf);
				}
				catch (IOException e) {
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}

			return buf[curChar++];
		}

		public String nextLine() {

			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			String str = "";

			try {
	            str = br.readLine();
	        }
	        catch (IOException e) {
	            e.printStackTrace();
	        }

	        return str;
		}

		public int nextInt() {

			int c = read();

			while(isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			int res = 0;

			do {
				if(c<'0'||c>'9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));

			return res * sgn;
		}

		public long nextLong() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			long res = 0;

			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}

			while (!isSpaceChar(c));
				return res * sgn;
		}

		public double nextDouble() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			double res = 0;

			while (!isSpaceChar(c) && c != '.') {

				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());

				if (c < '0' || c > '9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}

			if (c == '.') {

				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}

			return res * sgn;
		}

		public String readString() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			StringBuilder res = new StringBuilder();

			do {
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));

			return res.toString();
		}

		public boolean isSpaceChar(int c) {

			if (filter != null)
				return filter.isSpaceChar(c);

			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public String next() {
			return readString();
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

	public static void main(String args[]) throws Exception {
		new Thread(null, new cf1(),"cf1",1<<26).start();
	}
}


import static java.util.Arrays.deepToString;

import java.io.*;
import java.math.*;
import java.util.*;

public class C {

	final static long MOD = 1000000007;

	static void solve() {
		long[][] cnk = new long[100][100];
		cnk[0][0] = 1;
		for (int i = 1; i < cnk.length; i++) {
			cnk[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				cnk[i][j] = cnk[i - 1][j - 1] + cnk[i - 1][j];
			}
		}

		int n = nextInt(), k = nextInt() / 50;
		int[] total = new int[3];
		for (int i = 0; i < n; i++) {
			total[nextInt() / 50]++;
		}
		long[][][] d = new long[total[1] + 1][total[2] + 1][2];
		boolean[][][] was = new boolean[total[1] + 1][total[2] + 1][2];
		int[][][] dist = new int[total[1] + 1][total[2] + 1][2];
		was[total[1]][total[2]][0] = true;
		d[total[1]][total[2]][0] = 1;
		int[] q = new int[100000];
		int ql = 0, qr = 0;
		q[qr++] = total[1];
		q[qr++] = total[2];
		q[qr++] = 0;
		while (ql < qr) {
			int c1 = q[ql++];
			int c2 = q[ql++];
			int side = q[ql++];
			int curDist = dist[c1][c2][side];
			int maxTake1 = side == 0 ? c1 : total[1] - c1;
			int maxTake2 = side == 0 ? c2 : total[2] - c2;
			for (int take1 = 0; take1 <= maxTake1; take1++) {
				for (int take2 = 0; take2 <= maxTake2 && take1 + 2 * take2 <= k; take2++) {
					if (take1 == 0 && take2 == 0)
						continue;
					int nc1 = c1 + (side == 0 ? -take1 : take1);
					int nc2 = c2 + (side == 0 ? -take2 : take2);
					int nside = 1 - side;
					if (!was[nc1][nc2][nside]) {
						was[nc1][nc2][nside] = true;
						dist[nc1][nc2][nside] = curDist + 1;
						q[qr++] = nc1;
						q[qr++] = nc2;
						q[qr++] = nside;
					}
					int nDist = dist[nc1][nc2][nside];
					if (nDist == curDist + 1) {
						long add = d[c1][c2][side] * cnk[maxTake1][take1];
						add %= MOD;
						d[nc1][nc2][nside] += add * cnk[maxTake2][take2];
						d[nc1][nc2][nside] %= MOD;
					}
				}
			}
		}
		if (!was[0][0][1]) {
			writer.println(-1);
		} else {
			writer.println(dist[0][0][1]);
		}
		writer.println(d[0][0][1]);
	}

	public static void main(String[] args) throws Exception {
		reader = new BufferedReader(new InputStreamReader(System.in));
		writer = new PrintWriter(System.out);

		setTime();
		solve();
		printTime();
		printMemory();

		writer.close();
	}

	static BufferedReader reader;
	static PrintWriter writer;
	static StringTokenizer tok = new StringTokenizer("");
	static long systemTime;

	static void debug(Object... o) {
		System.err.println(deepToString(o));
	}

	static void setTime() {
		systemTime = System.currentTimeMillis();
	}

	static void printTime() {
		System.err.println("Time consumed: " + (System.currentTimeMillis() - systemTime));
	}

	static void printMemory() {
		System.err.println("Memory consumed: "
				+ (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000 + "kb");
	}

	static String next() {
		while (!tok.hasMoreTokens()) {
			String w = null;
			try {
				w = reader.readLine();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (w == null)
				return null;
			tok = new StringTokenizer(w);
		}
		return tok.nextToken();
	}

	static int nextInt() {
		return Integer.parseInt(next());
	}

	static long nextLong() {
		return Long.parseLong(next());
	}

	static double nextDouble() {
		return Double.parseDouble(next());
	}

	static BigInteger nextBigInteger() {
		return new BigInteger(next());
	}
}


import java.io.StreamTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		TokenizerReader in = new TokenizerReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    final static long MOD = 1000000007;
    public void solve(@SuppressWarnings("UnusedParameters") int testNumber, TokenizerReader in, PrintWriter out) {
        int n = in.nextInt(), maxWeight = in.nextInt();
        long[][] C = new long[n+1][n+1];
        for (int i = 0; i <= n; ++i) {
            C[i][0] = C[i][i] = 1;
            for (int j = 1; j < i; ++j)
                C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
        }
        maxWeight /= 50;
        int totalSmall = 0, totalBig = 0;
        for (int i = 0; i < n; ++i) {
            if (in.nextInt() == 50)
                ++totalSmall;
            else
                ++totalBig;
        }

        int[][][] time = new int[2][totalSmall + 1][totalBig + 1];
        for (int[][] ii: time)
            for (int[] i: ii)
                Arrays.fill(i, Integer.MAX_VALUE);
        for (int side = 0; side <= 1; ++side)
            for (int thisPeople = 0; thisPeople <= n; ++thisPeople)
                for (int thisSmall = Math.min(totalSmall, thisPeople); thisSmall >= 0; --thisSmall) {
                    int thisBig = thisPeople - thisSmall;
                    if (thisBig > totalBig)
                        continue;
                    int thatSmall = totalSmall - thisSmall;
                    int thatBig = totalBig - thisBig;
                    if (side == 1) {
                        if (thisPeople == n)
                            time[side][thisSmall][thisBig] = 0;
                        else if (thisSmall > 0)
                            time[side][thisSmall][thisBig] = 1 + time[0][thatSmall+1][thatBig];
                        else if (thisBig > 0)
                            time[side][thisSmall][thisBig] = 1 + time[0][thatSmall][thatBig+1];
                        continue;
                    }
                    if (thisPeople == 0)
                        continue;
                    for (int big = 0; big <= thisBig && 2*big <= maxWeight; ++big)
                        for (int small = 0; small <= thisSmall && 2*big+small <= maxWeight; ++small) {
                            if (big == thisBig && small == thisSmall)
                                time[side][thisSmall][thisBig] = 1;
                            else if (2*big + small > 1) {
                                int nextRightSmall = thatSmall + small;
                                int nextLeftBig, nextLeftSmall;
                                if (nextRightSmall > 0) {
                                    nextLeftBig = thisBig - big;
                                    nextLeftSmall = thisSmall + 1 - small;
                                } else {
                                    nextLeftBig = thisBig + 1 - big;
                                    nextLeftSmall = thisSmall - small;
                                }
                                if (nextLeftBig != thisBig || nextLeftSmall != thisSmall) {
                                    if (time[side][nextLeftSmall][nextLeftBig] < Integer.MAX_VALUE)
                                        time[side][thisSmall][thisBig] = Math.min(
                                                time[side][thisSmall][thisBig],
                                                time[side][nextLeftSmall][nextLeftBig] + 2
                                        );
                                }
                            }
                        }
                }

        int T = time[0][totalSmall][totalBig];
        if (T == Integer.MAX_VALUE) {
            out.println(-1);
            out.println(0);
            return;
        }
        long[][][] res = new long[2][totalSmall+1][totalBig+1];
        for (int t = 0; t <= T; ++t)
            for (int thisPeople = 0; thisPeople <= n; ++thisPeople)
                for (int thisSmall = 0; thisSmall <= totalSmall && thisSmall <= thisPeople; ++thisSmall) {
                    int thisBig = thisPeople - thisSmall;
                    if (thisBig > totalBig)
                        continue;
                    int side = 1 - t % 2;
                    if (time[side][thisSmall][thisBig] == 0) {
                        res[side][thisSmall][thisBig] = 1;
                        continue;
                    }
                    if (time[side][thisSmall][thisBig] != t)
                        continue;
                    for (int big = 0; big <= thisBig && 2*big <= maxWeight; ++big)
                        for (int small = 0; small <= thisSmall && 2*big + small <= maxWeight; ++small)
                            if (big + small > 0) {
                                int nextSmall = totalSmall - thisSmall + small;
                                int nextBig = totalBig - thisBig + big;
                                int nextSide = 1 - side;
                                if (time[nextSide][nextSmall][nextBig] == t-1) {
                                    long tmp = res[nextSide][nextSmall][nextBig] * C[thisBig][big] % MOD * C[thisSmall][small] % MOD;
                                    res[side][thisSmall][thisBig] += tmp;
                                    res[side][thisSmall][thisBig] %= MOD;
                                }
                            }
                }

        out.println(T);
        out.println(res[0][totalSmall][totalBig]);
    }
}

class TokenizerReader extends StreamTokenizer {
    public TokenizerReader(InputStream in) {
        super(new BufferedReader(new InputStreamReader(in)));
        defaultConfig();
    }

    public String nextString() {
        try {
            nextToken();
        } catch (IOException e) {
            throw new RuntimeException("nextString: exception in line " + lineno(), e);
        }
        return sval;
    }

    public int nextInt() {
        return Integer.parseInt(nextString());
    }

    public void defaultConfig() {
        resetSyntax();
        wordChars(33, 126);
        whitespaceChars(0, ' ');
    }

    }


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Abood2D {

	static int N, fifty, hundred, K;
	static int memo[][][];
	static int memo2[][][][];
	static final int MOD = (int) 1e9 + 7;
	static long[][] comb;

	static int solve(int t, int f, int h) {
		if(f == 0 && h == 0)
			return 0;

		if(memo[t][f][h] != -1)
			return memo[t][f][h];

		if(t == 1)
			return 1 + (f < fifty ? solve(0, f + 1, h) : solve(0, f, h + 1));

		int ans = (int) 1e6;

		for (int i = 0; i <= f; i++) {
			if(i * 50 > K)
				break;

			int j = Math.min(( K - i * 50) / 100, h);

			int totalW = i * 50 + j * 100;

			if(fifty - f + i > 0 && totalW > 50 || hundred - h + j > 1 && totalW > 100 || i == fifty && j == hundred)
				ans = Math.min(ans, solve(1, f - i, h - j));

		}

		return memo[t][f][h] = ans + 1;
	}

	static int solve2(int t, int f, int h, int r) {
		if(r == 0 && f == 0 && h == 0)
			return 1;

		if(r == 0)
			return 0;

		if(memo2[t][f][h][r] != -1)
			return memo2[t][f][h][r];

		int ans = 0;

		if(t == 1) {
			for (int i = 0; i <= fifty - f; ++i) {
				if(i * 50 > K)
					break;
				for (int j = 0; j <= hundred - h; ++j) {
					if(i == 0 && j == 0)
						continue;
					int totalW = i * 50 + j * 100;

					if(totalW > K)
						break;

					ans = (int) ((1l * ans + (1l * (nCk(fifty - f, i) * nCk(hundred - h, j)) % MOD) * solve2(0, f + i, h + j, r - 1) % MOD) % MOD);

				}

			}
		} else {
			for (int i = 0; i <= f; ++i) {
				if(i * 50 > K)
					break;
				for (int j = 0; j <= h; ++j) {
					if(i == 0 && j == 0)
						continue;
					int totalW = i * 50 + j * 100;

					if(totalW > K)
						break;

					ans = (int) ((1l * ans + (1l * (nCk(f, i) * nCk(h, j)) % MOD) * solve2(1, f - i, h - j, r - 1) % MOD)) % MOD;

				}

			}
		}

		return memo2[t][f][h][r] = ans;
	}

	static long nCk(int n, int k)		// O(n * k)
	{
		if(n < k)
			return 0;
		if(k == 0 || k == n)		//may add k == 1 as a base case for fast calculations
			return 1;
		if(comb[n][k] != -1)
			return comb[n][k];
		if(n - k < k)
			return comb[n][k] = nCk(n, n - k);		//reduce k to n - k
		return comb[n][k] = (((1l * n * nCk(n - 1, k - 1)) % MOD) * pow(k, MOD - 2)) % MOD;
	}

	static int pow(int x, long p) {
		if(p == 0)
			return 1;

		int ans = 1;
		if(p % 2 == 1)
			ans *= x;

		int c = pow(x, p / 2);

		ans = (int) ((1l * ((1l * ans * c) % MOD) * c) % MOD);

		return ans;
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		N = sc.nextInt();
		K = sc.nextInt();

		for (int i = 0; i < N; i++)
			if(sc.nextInt() == 50) fifty++; else hundred++;

		memo = new int[2][fifty + 1][hundred + 1];

		for (int i = 0; i < 2; i++)
			for (int j = 0; j <= fifty; j++)
				Arrays.fill(memo[i][j], -1);

		comb = new long[100 + 1][100 + 1];

		for (int i = 0; i <= 100; i++)
			Arrays.fill(comb[i], -1);

		int min = solve(0, fifty, hundred);

		if(min >= (int) 1e6){
			out.println(-1);
			out.println(0);
		}else {
			memo2 = new int[2][fifty + 1][hundred + 1][min + 1];

			for (int i = 0; i < 2; i++)
				for (int j = 0; j <= fifty; j++)
					for (int j2 = 0; j2 <= hundred; j2++)
						Arrays.fill(memo2[i][j][j2], -1);

			out.println(min);
			out.println(solve2(0, fifty, hundred, min));
		}

		out.flush();

	}

	static class Scanner

	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}

	}

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.util.ArrayDeque;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CGregAndFriends solver = new CGregAndFriends();
        solver.solve(1, in, out);
        out.close();
    }

    static class CGregAndFriends {
        long mod = 1000000007;
        long INF = (long) 1e18 + 1;
        PrintWriter out;
        InputReader in;
        long[][] nCr = new long[100][100];

        long f(long p, int a, int b, int c, int d) {
            p *= nCr[a][b];
            p %= mod;
            p *= nCr[c][d];
            p %= mod;
            return p;
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            this.out = out;
            this.in = in;
            int n = ni();
            int K = ni();
            int cnt1 = 0, cnt2 = 0;
            int i = 0, j = 0, k = 0;
            for (i = 0; i < 100; i++) {
                for (j = 0; j <= i; j++) {
                    if (j == 0 || j == i)
                        nCr[i][j] = 1;
                    else
                        nCr[i][j] = (nCr[i - 1][j] + nCr[i - 1][j - 1]) % mod;
                }
            }
            for (i = 0; i < n; i++) {
                if (ni() == 50)
                    cnt1++;
                else
                    cnt2++;
            }
            long[][][] dist = new long[200][200][2];
            long[][][] dp = new long[200][200][2];
            for (i = 0; i < 200; i++) {
                for (j = 0; j < 200; j++)
                    Arrays.fill(dist[i][j], INF);
            }
            dist[0][0][0] = 0;
            dp[0][0][0] = 1;
            ArrayDeque<Tuple> pq = new ArrayDeque<>();
            pq.add(new Tuple(0, 0, 0, 0));
            while (pq.size() > 0) {
                Tuple curr = pq.poll();
                int x = curr.x;
                int y = curr.y;
                int z = curr.z;
                long d = dist[x][y][z];
                if (z == 0) {
                    int rem_x = cnt1 - x;
                    int rem_y = cnt2 - y;
                    for (i = 0; i <= rem_x; i++) {
                        for (j = 0; j <= rem_y; j++) {
                            if (i + j == 0)
                                continue;
                            if (i * 50 + j * 100 > K)
                                break;
                            if (dist[i + x][j + y][z ^ 1] >= d + 1) {
                                if (dist[i + x][j + y][z ^ 1] > d + 1) {
                                    dist[i + x][j + y][z ^ 1] = d + 1;
                                    pq.add(new Tuple(dist[i + x][j + y][z ^ 1], i + x, j + y, z ^ 1));
                                    dp[i + x][j + y][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[i + x][j + y][z ^ 1] %= mod;
                                } else {
                                    dp[i + x][j + y][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[i + x][j + y][z ^ 1] %= mod;
                                }
                            }
                        }
                    }
                } else {
                    int rem_x = x;
                    int rem_y = y;
                    for (i = 0; i <= rem_x; i++) {
                        for (j = 0; j <= rem_y; j++) {
                            if (i + j == 0)
                                continue;
                            if (i * 50 + j * 100 > K)
                                break;
                            if (dist[x - i][y - j][z ^ 1] >= d + 1) {
                                if (dist[x - i][y - j][z ^ 1] > d + 1) {
                                    dist[x - i][y - j][z ^ 1] = d + 1;
                                    pq.add(new Tuple(dist[x - i][y - j][z ^ 1], x - i, y - j, z ^ 1));
                                    dp[x - i][y - j][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[x - i][y - j][z ^ 1] %= mod;
                                } else {
                                    dp[x - i][y - j][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[x - i][y - j][z ^ 1] %= mod;
                                }
                            }
                        }
                    }
                }
            }
            if (dist[cnt1][cnt2][1] == INF)
                pn(-1);
            else
                pn(dist[cnt1][cnt2][1]);
            pn(dp[cnt1][cnt2][1]);
        }

        int ni() {
            return in.nextInt();
        }

        void pn(long zx) {
            out.println(zx);
        }

        class Tuple {
            long d;
            int x;
            int y;
            int z;

            Tuple(long d, int x, int y, int z) {
                this.d = d;
                this.x = x;
                this.y = y;
                this.z = z;
            }

        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new UnknownError();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuffer res = new StringBuffer();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.StringTokenizer;

public class C {

    final int p = 1000000007;

    void do_solve() {
        int n = nextInt();
        int k = nextInt();
        k /= 50;

        long c[][] = new long[100][100];
        for(int i = 0; i < 100; i++) {
            c[i][0] = 1;
            if (i == 0){
                continue;
            }
            for(int j = 1; j < 100; j++) {
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % p;
            }
        }

        int a = 0, b = 0;
        for(int i = 0; i < n; i++) {
            int r = nextInt();
            if (r == 50) {
                a++;
            } else {
                b++;
            }
        }

        long ans_d[][] = new long[a + 1][b + 1];
        long ans_c[][] = new long[a + 1][b + 1];

        int inf = 1 << 20;

        for(int i = 0; i <= a; i++)
            for(int j = 0; j <= b; j++) {
                ans_d[i][j] = inf;
                ans_c[i][j] = 0;
            }

        ArrayList<Integer> nowa = new ArrayList<>(0);
        ArrayList<Integer> nowb = new ArrayList<>(0);

        nowa.add(0);
        nowb.add(0);
        ans_d[0][0] = -1;
        ans_c[0][0] = 1;

        while (nowa.size() > 0) {
            int x = nowa.remove(0);
            int y = nowb.remove(0);

            for(int i = 0; i <= x; i++) {
                for(int j = 0; j <= y; j++) {
                    if (i == 0 && j == 0 && !(x == 0 && y == 0))
                        continue;
                    if (i + 2 * j > k)
                        break;

                    long ans = (c[x][i] * c[y][j]) % p;

                    int q_a = a - x + i;
                    int q_b = b - y + j;

                    for(int i2 = 0; i2 <= q_a; i2++) {
                        for(int j2 = 0; j2 <= q_b; j2++) {
                            if (i2 == 0 && j2 == 0)
                                continue;
                            if (i2 + 2 * j2 > k)
                                break;

                            int nx = x - i + i2;
                            int ny = y - j + j2;

                            if (ans_d[nx][ny] >= ans_d[x][y] + 2) {
                                long ans2 = (c[q_a][i2] * c[q_b][j2]) % p;
                                ans_c[nx][ny] = (ans_c[nx][ny] + (ans_c[x][y] * ((ans * ans2) % p ) )) % p;
                            }

                            if (ans_d[nx][ny] > ans_d[x][y] + 2) {
                                ans_d[nx][ny] = ans_d[x][y] + 2;
                                nowa.add(nx);
                                nowb.add(ny);
                            }

                        }
                    }
                }
            }
        }

        out.println(ans_d[a][b] == inf ? -1 :  ans_d[a][b]);
        out.println(ans_c[a][b]);
    }

    void mainProgram() {
        init(null);
        int test = 0;
        long T = System.currentTimeMillis();
        do_solve();
        System.err.println("Time on test " + (test++) + ": "
                + (System.currentTimeMillis() - T) + " ms");
        out.close();
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }

    void init(String filename) {
        Locale.setDefault(Locale.US);
        if (filename != null)
            try {
                in = new BufferedReader(new FileReader(filename + ".in"));
                out = new PrintWriter(filename + ".out");
            } catch (Exception e) {
                e.printStackTrace();
                filename = null;
            }
        if (filename == null) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
        st = new StringTokenizer("");
    }

    static BufferedReader in;
    static StringTokenizer st = new StringTokenizer("");
    static PrintWriter out;
    static long systemTime;

    public static void main(String[] args) {
        try {
            setTime();
            new C().mainProgram();
            printTime();
            printMemory();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void setTime() {
        systemTime = System.currentTimeMillis();
    }

    static void printTime() {
        System.err.println("Time consumed: "
                + (System.currentTimeMillis() - systemTime));
    }

    static void printMemory() {
        System.err.println("Memory consumed: "
                + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime()
                        .freeMemory()) / 1000 + "kb");
    }

    boolean hasMoreTokens() {
        try {
            while (!st.hasMoreTokens()) {
                st = new StringTokenizer(in.readLine());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return st.hasMoreTokens();
    }

    String nextToken() {
        return hasMoreTokens() ? st.nextToken() : null;
    }

    Integer nextInt() {
        return Integer.parseInt(nextToken());
    }

    Double nextDouble() {
        return Double.parseDouble(nextToken());
    }

    Long nextLong() {
        return Long.parseLong(nextToken());
    }

    BigInteger add(BigInteger A, BigInteger B) {
        return A.add(B);
    }

    BigInteger mult(BigInteger A, BigInteger B) {
        return A.multiply(B);
    }

    BigInteger sub(BigInteger A, BigInteger B) {
        return A.subtract(B);
    }

    BigInteger div(BigInteger A, BigInteger B) {
        return A.divide(B);
    }

    BigInteger mi(BigInteger A) {
        return (BigInteger.ZERO).subtract(A);
    }

    BigInteger sq(BigInteger A) {
        return A.multiply(A);
    }

    BigInteger val(long a) {
        return BigInteger.valueOf(a);
    }

    int cmp(BigInteger a, BigInteger b) {
        return a.compareTo(b);
    }

    BigInteger gcd(BigInteger a, BigInteger b) {
        if (cmp(a, val(0)) < 0)
            a = mi(a);
        if (cmp(b, val(0)) < 0)
            b = mi(b);
        return a.gcd(b);
    }
}


import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.AbstractMap;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Egor Kulikov (egor@egork.net)
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
	int[][] moves;
	long[][] ways;
	int size;
	long[][] c;
	static final long MOD = (long) (1e9 + 7);
	int maxHeavy, maxLight;

    public void solve(int testNumber, InputReader in, OutputWriter out) {
		int count = in.readInt();
		c = IntegerUtils.generateBinomialCoefficients(count + 1, MOD);
		size = in.readInt() / 50;
		int[] types = IOUtils.readIntArray(in, count);
		int light = 0;
		int heavy = 0;
		for (int i : types) {
			if (i == 100)
				heavy++;
			else
				light++;
		}
		maxHeavy = heavy;
		maxLight = light;
		if (count == 1) {
			if (types[0] <= 50 * size) {
				out.printLine(1);
				out.printLine(1);
			} else {
				out.printLine(-1);
				out.printLine(0);
			}
			return;
		}
		moves = new int[heavy + 1][light + 1];
		ways = new long[heavy + 1][light + 1];
		ArrayUtils.fill(moves, -1);
		ArrayUtils.fill(ways, -1);
		int moves = calculateMoves(heavy, light);
		if (moves == Integer.MAX_VALUE / 2) {
			out.printLine(-1);
			out.printLine(0);
			return;
		}
		out.printLine(moves);
		out.printLine(calculateWays(heavy, light));
    }

	private long calculateWays(int heavy, int light) {
		if (ways[heavy][light] != -1)
			return ways[heavy][light];
		if (2 * heavy + light <= size)
			return ways[heavy][light] = 1;
		ways[heavy][light] = 0;
		for (int i = 0; i <= heavy && 2 * i <= size; i++) {
			for (int j = 0; j <= light && 2 * i + j <= size; j++) {
				if (i + j == 0)
					continue;
				for (int k = 0; k <= maxHeavy - heavy + i && 2 * k <= size; k++) {
					for (int l = 0; l <= maxLight - light + j && 2 * k + l <= size; l++) {
						if (k + l == 0)
							continue;
						if (calculateMoves(heavy - i + k, light - j + l) == moves[heavy][light] - 2)
						{
							ways[heavy][light] += calculateWays(heavy - i + k, light - j + l) * c[heavy][i] % MOD *
								c[light][j] % MOD * c[maxHeavy - heavy + i][k] % MOD * c[maxLight - light + j][l] % MOD;
						}
					}
				}
			}
		}
		return ways[heavy][light] %= MOD;
	}

	private int calculateMoves(int heavy, int light) {
		if (heavy > maxHeavy || light > maxLight)
			return Integer.MAX_VALUE / 2;
		if (moves[heavy][light] != -1)
			return moves[heavy][light];
		if (2 * heavy + light <= size)
			return moves[heavy][light] = 1;
		moves[heavy][light] = Integer.MAX_VALUE / 2;
		for (int i = 0; i <= heavy && 2 * i <= size; i++) {
			for (int j = 0; j <= light && 2 * i + j <= size; j++) {
				if (i == 0 && j <= 1)
					continue;
				if (i != 1 || j != 0) {
					int result = calculateMoves(heavy - i + 1, light - j);
					moves[heavy][light] = Math.min(moves[heavy][light], result + 2);
				}
				int result = calculateMoves(heavy - i, light - j + 1);
				moves[heavy][light] = Math.min(moves[heavy][light], result + 2);
			}
		}
		return moves[heavy][light];
	}
}

class InputReader {

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

    public void printLine(Object...objects) {
		print(objects);
		writer.println();
	}

	public void close() {
		writer.close();
	}

	}

class IntegerUtils {

    public static long[][] generateBinomialCoefficients(int n, long module) {
		long[][] result = new long[n + 1][n + 1];
		if (module == 1)
			return result;
		for (int i = 0; i <= n; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
				if (result[i][j] >= module)
					result[i][j] -= module;
			}
		}
		return result;
	}

	}

class IOUtils {

	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}

	}

class ArrayUtils {

	public static void fill(long[][] array, long value) {
		for (long[] row : array)
			Arrays.fill(row, value);
	}

	public static void fill(int[][] array, int value) {
		for (int[] row : array)
			Arrays.fill(row, value);
	}

	}

abstract class IntCollection {
	public abstract IntIterator iterator();
	public abstract int size();

	}

interface IntIterator {
	public int value() throws NoSuchElementException;
	/*
	 * @throws NoSuchElementException only if iterator already invalid
	 */
	public void advance() throws NoSuchElementException;
	public boolean isValid();
}

abstract class IntList extends IntCollection {
	private static final int INSERTION_THRESHOLD = 8;

	public abstract int get(int index);
	public abstract void set(int index, int value);

	public IntIterator iterator() {
		return new IntIterator() {
			private int size = size();
			private int index = 0;

			public int value() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				return get(index);
			}

			public void advance() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				index++;
			}

			public boolean isValid() {
				return index < size;
			}
		};
	}

	private void swap(int first, int second) {
		if (first == second)
			return;
		int temp = get(first);
		set(first, get(second));
		set(second, temp);
	}

	public IntSortedList inPlaceSort(IntComparator comparator) {
		quickSort(0, size() - 1, size(), comparator);
		return new IntSortedArray(this, comparator);
	}

	private void quickSort(int from, int to, int remaining, IntComparator comparator) {
		if (to - from < INSERTION_THRESHOLD) {
			insertionSort(from, to, comparator);
			return;
		}
		if (remaining == 0) {
			heapSort(from, to, comparator);
			return;
		}
		remaining >>= 1;
		int pivotIndex = (from + to) >> 1;
		int pivot = get(pivotIndex);
		swap(pivotIndex, to);
		int storeIndex = from;
		int equalIndex = to;
		for (int i = from; i < equalIndex; i++) {
			int value = comparator.compare(get(i), pivot);
			if (value < 0)
				swap(storeIndex++, i);
			else if (value == 0)
				swap(--equalIndex, i--);
		}
		quickSort(from, storeIndex - 1, remaining, comparator);
		for (int i = equalIndex; i <= to; i++)
			swap(storeIndex++, i);
		quickSort(storeIndex, to, remaining, comparator);
	}

	private void heapSort(int from, int to, IntComparator comparator) {
		for (int i = (to + from - 1) >> 1; i >= from; i--)
			siftDown(i, to, comparator, from);
		for (int i = to; i > from; i--) {
			swap(from, i);
			siftDown(from, i - 1, comparator, from);
		}
	}

	private void siftDown(int start, int end, IntComparator comparator, int delta) {
		int value = get(start);
		while (true) {
			int child = ((start - delta) << 1) + 1 + delta;
			if (child > end)
				return;
			int childValue = get(child);
			if (child + 1 <= end) {
				int otherValue = get(child + 1);
				if (comparator.compare(otherValue, childValue) > 0) {
					child++;
					childValue = otherValue;
				}
			}
			if (comparator.compare(value, childValue) >= 0)
				return;
			swap(start, child);
			start = child;
		}
	}

	private void insertionSort(int from, int to, IntComparator comparator) {
		for (int i = from + 1; i <= to; i++) {
			int value = get(i);
			for (int j = i - 1; j >= from; j--) {
				if (comparator.compare(get(j), value) <= 0)
					break;
				swap(j, j + 1);
			}
		}
	}

	public IntSortedList sort(IntComparator comparator) {
		return new IntArray(this).inPlaceSort(comparator);
	}

	}

interface IntComparator {
    public static final IntComparator DEFAULT = new IntComparator() {
        public int compare(int first, int second) {
            if (first < second)
                return -1;
            if (first > second)
                return 1;
            return 0;
        }
    };

	public int compare(int first, int second);
}

abstract class IntSortedList extends IntList {
	protected final IntComparator comparator;

	protected IntSortedList(IntComparator comparator) {
		this.comparator = comparator;
	}

	public void set(int index, int value) {
		throw new UnsupportedOperationException();
	}

	public IntSortedList inPlaceSort(IntComparator comparator) {
		if (comparator == this.comparator)
			return this;
		throw new UnsupportedOperationException();
	}

	public IntSortedList sort(IntComparator comparator) {
		if (comparator == this.comparator)
			return this;
		return super.sort(comparator);
	}

	protected void ensureSorted() {
		int size = size();
		if (size == 0)
			return;
		int last = get(0);
		for (int i = 1; i < size; i++) {
			int current = get(i);
			if (comparator.compare(last, current) > 0)
				throw new IllegalArgumentException();
			last = current;
		}
	}

	}

class IntArray extends IntList {
	private final int[] array;

	public IntArray(int[] array) {
		this.array = array;
	}

	public IntArray(IntCollection collection) {
		array = new int[collection.size()];
		int i = 0;
		for (IntIterator iterator = collection.iterator(); iterator.isValid(); iterator.advance())
			array[i++] = iterator.value();
	}

	public int get(int index) {
		return array[index];
	}

	public void set(int index, int value) {
		array[index] = value;
	}

	public int size() {
		return array.length;
	}

	}

class IntSortedArray extends IntSortedList {
	private final int[] array;

	public IntSortedArray(int[] array) {
		this(array, IntComparator.DEFAULT);
	}

	public IntSortedArray(IntCollection collection) {
		this(collection, IntComparator.DEFAULT);
	}

	public IntSortedArray(int[] array, IntComparator comparator) {
		super(comparator);
		this.array = array;
		ensureSorted();
	}

	public IntSortedArray(IntCollection collection, IntComparator comparator) {
		super(comparator);
		array = new int[collection.size()];
		int i = 0;
		for (IntIterator iterator = collection.iterator(); iterator.isValid(); iterator.advance())
			array[i++] = iterator.value();
		ensureSorted();
	}

	public int get(int index) {
		return array[index];
	}

	public int size() {
		return array.length;
	}
}


import java.io.*;
import java.util.*;

public class Main {
	static Scanner in; static int next() throws Exception {return in.nextInt();}
	static PrintWriter out;
//	static StreamTokenizer in; static int next() throws Exception {in.nextToken(); return (int) in.nval;}
//	static BufferedReader in;

	static int mod = 1000000007;

	public static void main(String[] args) throws Exception {
		in = new Scanner(System.in);
//		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		int n = next();
		int k = next() / 50;

		int[] x = new int[n];
		for (int i = 0; i < n; i++) x[i] = next() / 50;

		int count1 = 0;
		int count2 = 0;

		for (int i = 0; i < n; i++)
			if (x[i] == 1) count1++;
			else count2++;
//		out.println(k + " " + count1 + " " + count2) ;

		if ((k == 0) ||
			(k == 1 && (count2 > 0 || count1 > 1)) ||
			(k == 2 && (count2 > 0 && count1 < 2)) ||
			(k == 3 && (count1 < 1))) {
			out.println(-1);
			out.println(0);
			out.close();
			return;
		}

		int[][] c = new int[100][100];
		for (int i = 0; i < 100; i++) c[i][0] = c[i][i] = 1;
		for (int i = 0; i < 100; i++)
			for (int j = 1; j < i; j++) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;

		long[][] count = new long[count1 + 1][count2 + 1];
		count[0][0] = 1;
		for (int iter = 0; iter < 1000; iter++) {
			long[][] cnt = new long[count1 + 1][count2 + 1];

			if (iter % 2 == 0) {
				for (int i = 0; i <= count1; i++)
					for (int j = 0; j <= count2; j++)
						for (int t = 0; t + i <= count1; t++)
							for (int s = 0; s + j <= count2 && t + 2*s <= k; s++) if (t + s != 0) {
								cnt[i + t][j + s] = (cnt[i + t][j + s] + ((count[i][j] * c[count1 - i][t]) % mod * c[count2 - j][s]) % mod) % mod;
							}
			} else {
				for (int i = 0; i <= count1; i++)
					for (int j = 0; j <= count2; j++)
						for (int t = 0; t + i <= count1; t++)
							for (int s = 0; s + j <= count2 && t + 2*s <= k; s++) if (t + s != 0) {
								cnt[i][j] = (cnt[i][j] + ((count[i + t][j + s] * c[i + t][t]) % mod * c[s + j][s]) % mod) % mod;
							}
			}
			count = cnt;
			if (count[count1][count2] != 0) {
				out.println(iter + 1);
				out.println(count[count1][count2]);
				break;
			}
//			out.println(count[0][0] + " " + count[1][0]);
		}

		out.close();
	}
}


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Niyaz Nigmatullin
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		FastPrinter out = new FastPrinter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {

    static final int MOD = 1000000007;
    static long[][] C;
    static {
        C = new long[55][55];
        for (int i = 0; i < C.length; i++) {
            C[i][0] = 1;
            for (int j = 1; j <= i; j++) {
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
                if (C[i][j] >= MOD) {
                    C[i][j] -= MOD;
                }
            }
        }
    }
    public void solve(int testNumber, FastScanner in, FastPrinter out) {
        int n = in.nextInt();
        int k = in.nextInt();
        k /= 50;
        int cn1 = 0;
        int cn2 = 0;
        for (int i = 0; i < n; i++) {
            if (in.nextInt() == 50) {
                ++cn1;
            } else {
                ++cn2;
            }
        }
        int[][] tries = new int[cn1 + 1][cn2 + 1];
        int[][] ways = new int[cn1 + 1][cn2 + 1];
        for (int[] d : tries) {
            Arrays.fill(d, Integer.MAX_VALUE);
        }
        for (int i = 0; i <= cn1; i++) {
            for (int j = 0; j <= cn2; j++) {
                if (i + j == 0) {
                    continue;
                }
                if (i + 2 * j <= k) {
                    tries[i][j] = 1;
                    ways[i][j] = (int) (C[cn1][i] * C[cn2][j] % MOD);
                }
            }
        }
        boolean changed = true;
        int q = 1;
        while (changed) {
            changed = false;
            for (int c1 = 0; c1 <= cn1; c1++) {
                for (int c2 = 0; c2 <= cn2; c2++) {
                    int ct = tries[c1][c2];
                    if (ct != q) {
                        continue;
                    }
                    long cw = ways[c1][c2];
                    for (int b1 = 0; b1 <= c1 && b1 <= c1; b1++) {
                        for (int b2 = 0; b2 <= c2 && b2 <= c2; b2++) {
                            if (b1 + b2 == 0 || b1 + b2 * 2 > k) {
                                continue;
                            }
                            long dw = (cw * C[c1][b1] % MOD * C[c2][b2] % MOD);
                            int left1 = cn1 - c1 + b1;
                            int left2 = cn2 - c2 + b2;
                            for (int i = 0; i <= left1; i++) {
                                for (int j = 0; j <= left2; j++) {
                                    if (i + j == 0) continue;
                                    if (i + 2 * j > k) {
                                        continue;
                                    }
                                    int d1 = c1 - b1 + i;
                                    int d2 = c2 - b2 + j;
                                    if (tries[d1][d2] > ct + 2) {
                                        tries[d1][d2] = ct + 2;
                                        ways[d1][d2] = (int) (dw * C[left1][i] % MOD * C[left2][j] % MOD);
                                        changed = true;
                                    } else if (tries[d1][d2] == ct + 2) {
                                        ways[d1][d2] = (int) ((ways[d1][d2] + dw * C[left1][i] % MOD * C[left2][j] % MOD) % MOD);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            q += 2;
        }
        if (tries[cn1][cn2] == Integer.MAX_VALUE) {
            out.println(-1);
            out.println(0);
            return;
        }
        out.println(tries[cn1][cn2]);
        out.println(ways[cn1][cn2]);
    }

}

class FastScanner extends BufferedReader {

    boolean isEOF;

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
            if (isEOF && ret < 0) {
                throw new InputMismatchException();
            }
            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

    }

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.io.IOException;
import java.util.Queue;
import java.util.LinkedList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CGregAndFriends solver = new CGregAndFriends();
        solver.solve(1, in, out);
        out.close();
    }

    static class CGregAndFriends {
        long mod = 1000000007;
        long INF = (long) 1e18 + 1;
        PrintWriter out;
        InputReader in;
        long[][] nCr = new long[100][100];

        long f(long p, int a, int b, int c, int d) {
            p *= nCr[a][b];
            p %= mod;
            p *= nCr[c][d];
            p %= mod;
            return p;
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            this.out = out;
            this.in = in;
            int n = ni();
            int K = ni();
            int cnt1 = 0, cnt2 = 0;
            int i = 0, j = 0, k = 0;
            for (i = 0; i < 100; i++) {
                for (j = 0; j <= i; j++) {
                    if (j == 0 || j == i)
                        nCr[i][j] = 1;
                    else
                        nCr[i][j] = (nCr[i - 1][j] + nCr[i - 1][j - 1]) % mod;
                }
            }
            for (i = 0; i < n; i++) {
                if (ni() == 50)
                    cnt1++;
                else
                    cnt2++;
            }
            long[][][] dist = new long[200][200][2];
            long[][][] dp = new long[200][200][2];
            for (i = 0; i < 200; i++) {
                for (j = 0; j < 200; j++)
                    Arrays.fill(dist[i][j], INF);
            }
            dist[0][0][0] = 0;
            dp[0][0][0] = 1;
            Queue<Tuple> pq = new LinkedList<Tuple>();
            pq.add(new Tuple(0, 0, 0, 0));
            while (pq.size() > 0) {
                Tuple curr = pq.poll();
                int x = curr.x;
                int y = curr.y;
                int z = curr.z;
                long d = dist[x][y][z];
                if (z == 0) {
                    int rem_x = cnt1 - x;
                    int rem_y = cnt2 - y;
                    for (i = 0; i <= rem_x; i++) {
                        for (j = 0; j <= rem_y; j++) {
                            if (i + j == 0)
                                continue;
                            if (i * 50 + j * 100 > K)
                                break;
                            if (dist[i + x][j + y][z ^ 1] >= d + 1) {
                                if (dist[i + x][j + y][z ^ 1] > d + 1) {
                                    dist[i + x][j + y][z ^ 1] = d + 1;
                                    pq.add(new Tuple(dist[i + x][j + y][z ^ 1], i + x, j + y, z ^ 1));
                                    dp[i + x][j + y][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[i + x][j + y][z ^ 1] %= mod;
                                } else {
                                    dp[i + x][j + y][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[i + x][j + y][z ^ 1] %= mod;
                                }
                            }
                        }
                    }
                } else {
                    int rem_x = x;
                    int rem_y = y;
                    for (i = 0; i <= rem_x; i++) {
                        for (j = 0; j <= rem_y; j++) {
                            if (i + j == 0)
                                continue;
                            if (i * 50 + j * 100 > K)
                                break;
                            if (dist[x - i][y - j][z ^ 1] >= d + 1) {
                                if (dist[x - i][y - j][z ^ 1] > d + 1) {
                                    dist[x - i][y - j][z ^ 1] = d + 1;
                                    pq.add(new Tuple(dist[x - i][y - j][z ^ 1], x - i, y - j, z ^ 1));
                                    dp[x - i][y - j][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[x - i][y - j][z ^ 1] %= mod;
                                } else {
                                    dp[x - i][y - j][z ^ 1] += f(dp[x][y][z], rem_x, i, rem_y, j);
                                    dp[x - i][y - j][z ^ 1] %= mod;
                                }
                            }
                        }
                    }
                }
            }
            if (dist[cnt1][cnt2][1] == INF)
                pn(-1);
            else
                pn(dist[cnt1][cnt2][1]);
            pn(dp[cnt1][cnt2][1]);
        }

        int ni() {
            return in.nextInt();
        }

        void pn(long zx) {
            out.println(zx);
        }

        class Tuple {
            long d;
            int x;
            int y;
            int z;

            Tuple(long d, int x, int y, int z) {
                this.d = d;
                this.x = x;
                this.y = y;
                this.z = z;
            }

        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new UnknownError();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuffer res = new StringBuffer();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}


import java.io.*;
import java.util.*;

public class Pr295C {
	public static void main(String[] args) throws IOException {
		new Pr295C().run();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out, true);
		solve();
		out.flush();
	}

	final int mod = 1000000007;
	int[][][] d;
	long[][][] cnt;
	int A;
	int B;
	int k;
	int[][] c;

	void smthLikeBfs() {
		LinkedList<Integer> typeQ = new LinkedList<Integer>();
		LinkedList<Integer> numAQ = new LinkedList<Integer>();
		LinkedList<Integer> numBQ = new LinkedList<Integer>();
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < A; j++) {
				for (int z = 0; z < B; z++) {
					d[i][j][z] = Integer.MAX_VALUE;
				}
			}
		}
		boolean[][][] used = new boolean[2][A + 1][B + 1];
		d[0][A][B] = 0;
		cnt[0][A][B] = 1;
		used[0][A][B] = true;
		typeQ.add(0);
		numAQ.add(A);
		numBQ.add(B);
		while (!typeQ.isEmpty()) {
			int curt = typeQ.pollFirst();
			int cura = numAQ.pollFirst();
			int curb = numBQ.pollFirst();
			for (int x = 0; x <= cura; x++) {
				for (int y = 0; y <= curb; y++) {
					if (50 * x + y * 100 <= k && x + y > 0) {
						if (!used[(curt + 1) % 2][A - cura + x][B - curb + y]) {
							d[(curt + 1) % 2][A - cura + x][B - curb + y] = d[curt][cura][curb] + 1;
							used[(curt + 1) % 2][A - cura + x][B - curb + y] = true;
							typeQ.add((curt + 1) % 2);
							numAQ.add(A - cura + x);
							numBQ.add(B - curb + y);
						}
						if (d[(curt + 1) % 2][A - cura + x][B - curb + y] == d[curt][cura][curb] + 1) {
							cnt[(curt + 1) % 2][A - cura + x][B - curb + y] += (((cnt[curt][cura][curb] * c[cura][x]) % mod) * c[curb][y])
									% mod;
							cnt[(curt + 1) % 2][A - cura + x][B - curb + y] %= mod;
						}
					}
				}
			}
		}
	}

	void solve() throws IOException {
		int n = nextInt();
		k = nextInt();
		A = 0; // number of thin people
		B = 0; // number of fat people
		for (int i = 0; i < n; i++) {
			if (nextInt() == 50) {
				A++;
			} else {
				B++;
			}
		}
		d = new int[2][A + 1][B + 1]; // type, how many As, how many Bs
		cnt = new long[2][A + 1][B + 1];
		c = new int[n + 1][n + 1];
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j <= i; j++) {
				if (j == 0) {
					c[i][j] = 1;
				} else if (i == j) {
					c[i][j] = 1;
				} else {
					c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
				}
			}
		}
		smthLikeBfs();
		if (cnt[1][A][B] == 0) {
			out.println(-1);
			out.println(0);
			return;
		}
		out.println(d[1][A][B]);
		out.println(cnt[1][A][B]);
	}
}


import static java.lang.System.*;
import static java.lang.Math.*;

import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;

public class C295 {
    public static Scanner sc=new Scanner(in);
    //public static Random sc=new Random();

    class Node{
        public int id;
        public int s,b,lr;
        public int val;
        public Node(int _s,int _b,int _lr){
            s=_s;b=_b;lr=_lr;
        }
//      public String toString() {
//          return val+" ("+id+")=>"+link;
//      }
    }
    class Edge{
        public int from;
        public int to;
        public int c;
        public Edge(int from,int to){
            this.from=from;
            this.to=to;
        }
        public Edge(int from,int to,int c){
            this(from,to);
            this.c=c;
        }
        public String toString() {
            return from+"→"+to;
        }
    }

    //nCr
    public long[][] comb(int n){
        long[][] comb=new long[n][n];
        for(int i=0;i<n;i++){
            comb[i][0]=comb[i][i]=1;
            for(int j=1;j<=i;j++){
                comb[i][j]=(j==0)?1:(comb[i-1][j]+comb[i-1][j-1])%mod;
            }
        }
        return comb;
    }

    final int mod=1000000007;
    void run() throws RuntimeException{
        final int n=sc.nextInt(),k=sc.nextInt();

        long[][] c=comb(n+1);

        int s=0,b=0;
        for(int i=0;i<n;i++){
            int v=sc.nextInt();
            if(v==50)
                s++;
            else b++;
        }

        Node[][][] nodes=new Node[s+1][b+1][2];
        long[][][] count=new long[s+1][b+1][2];
        boolean[][][] passed=new boolean[s+1][b+1][2];

        count[s][b][0]=1;
        Queue<Node> que=new LinkedList<>();
        for(int si=0;si<=s;si++)for(int bi=0;bi<=b;bi++){
            nodes[si][bi][0]=new Node(si,bi,0);
            nodes[si][bi][1]=new Node(si,bi,1);
        }

        que.add(nodes[s][b][0]);
        passed[s][b][0]=true;
        int turn=0;
        while(!que.isEmpty()){
            Queue<Node> tmp=new LinkedList<>();
            while(!que.isEmpty()){
                Node node=que.poll();
                int lr=node.lr==0?1:0;
                for(int si=0;si<=s;si++)for(int bi=0;bi<=b;bi++){
                    if(passed[si][bi][lr])continue;
                    if(node.s==si && node.b==bi)continue;
                    if(node.lr==0 && node.s>=si && node.b>=bi && abs(node.s-si)*50+abs(node.b-bi)*100<=k){//l to r
                        if(!tmp.contains(nodes[si][bi][lr]))tmp.add(nodes[si][bi][lr]);
                        count[si][bi][lr]=(count[si][bi][lr]+(c[node.s][abs(node.s-si)]*c[node.b][abs(node.b-bi)]%mod*count[node.s][node.b][node.lr]%mod))%mod;
                    }
                    if(node.lr==1 && node.s<=si && node.b<=bi && abs(node.s-si)*50+abs(node.b-bi)*100<=k){//r to l
                        if(!tmp.contains(nodes[si][bi][lr]))tmp.add(nodes[si][bi][lr]);
                        count[si][bi][lr]=(count[si][bi][lr]+(c[s-node.s][abs(node.s-si)]*c[b-node.b][abs(node.b-bi)]%mod*count[node.s][node.b][node.lr]%mod))%mod;
                    }
                }
            }
            for(Node node:tmp)passed[node.s][node.b][node.lr]=true;

            que=tmp;
            turn++;
            if(passed[0][0][1]){//end
                ln(turn);
                ln(count[0][0][1]);
                return;
            }
        }
        ln(-1);
        ln(0);
    }

    public static void main(String[] args) {
        new C295().run();
    }

    //output lib
    static final String br=System.getProperty("line.separator");
    static final String[] asep=new String[]{""," ",br,br+br};
    static String str(boolean o){
        return o?"YES":"NO";
    }
    static <K,V> String str(Map<K, V> map){
        StringBuilder sb=new StringBuilder();
        boolean isFirst=true;
        for(Entry<K,V> set:map.entrySet()){
            if(!isFirst)sb.append(br);
            sb.append(str(set.getKey())).append(":").append(str(set.getValue()));
            isFirst=false;
        }
        return sb.toString();
    }
    static <E> String str(Collection<E> list){
        StringBuilder sb=new StringBuilder();
        boolean isFirst=true;
        for(E e:list){
            if(!isFirst)sb.append(" ");
            sb.append(str(e));
            isFirst=false;
        }
        return sb.toString();
    }
    static String str(Object o){
        int depth=_getArrayDepth(o);
        if(depth>0)return _strArray(o,depth);
        return o.toString();
    }
    static int _getArrayDepth(Object o){
        if(!o.getClass().isArray() || Array.getLength(o)==0) return 0;
        return  1+_getArrayDepth(Array.get(o,0));
    }
    //depth ex A[10]…1 A[10][10]…2 exception A[0]…0 A[10][0]…1 A[0][0]…0
    static String _strArray(Object o,int depth){
        if(depth==0) return str(o);
        StringBuilder sb=new StringBuilder();
        for(int i=0,len=Array.getLength(o);i<len;i++){
            if(i!=0)sb.append(asep[depth]);
            sb.append(_strArray(Array.get(o,i),depth-1));
        }
        return sb.toString();
    }
    static void pr(Object... os){
        boolean isFirst=true;
        for(Object o:os){
            if(!isFirst)out.print(" ");
            out.print(o);
            isFirst=false;
        }
    }
    static void ln(){
        out.println();
    }
    static void ln(Object... os){
        for(Object o:os){
            pr(o);ln();
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class C {
	BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    public class State{
    	int c50, c100, side, step;
    	public State(int c50, int c100, int side, int step){
    		this.c50 = c50;
    		this.c100 = c100;
    		this.side = side;
    		this.step = step;
    	}
    }

    long MODULAR = 1000000007;

    public static long[][] generateCombo(int MAX, long MOD) {
		long[][] result = new long[MAX + 1][MAX + 1];
		if (MOD == 1)
			return result;
		for (int i = 0; i <= MAX; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
				if (result[i][j] >= MOD)
					result[i][j] -= MOD;
			}
		}
		return result;
	}

	public void solve() throws IOException {
		int N = nextInt();
		int K = nextInt();
		int c50 = 0; int c100 = 0;
		for(int i = 0; i < N; i++)
			if( nextInt() == 50)
				c50++;
			else
				c100++;

		long[][] c = generateCombo( Math.max(c50, c100), MODULAR);

		long dp[][][] = new long[c50+1][c100+1][2];
		int[][][] visited = new int[c50+1][c100+1][2];
		for(int i = 0; i <= c50; i++)
			for(int j = 0; j <= c100; j++)
				Arrays.fill(visited[i][j], -1);

		dp[c50][c100][0] = 1;
		State state = new State( c50, c100, 0, 0 );
		Queue<State> queue = new LinkedList<State>();
		queue.add(state);
		visited[c50][c100][0] = 0;

		while( !queue.isEmpty() ){
			State current = queue.poll();

//			System.out.println( current.c50 + ", " + current.c100 + ", " + current.side + ", " + current.step );

			int iTo = current.side == 0? current.c50: c50 - current.c50;
			int jTo = current.side == 0? current.c100: c100 - current.c100;

			for(int i = 0; i <= iTo; i++){
				for(int j = 0; j <= jTo; j++){
					if( i == 0 && j == 0 ) continue;
					if( i * 50 + j * 100 > K ) continue;

					int newc50 = current.side == 0? current.c50 - i: current.c50 + i;
					int newc100 = current.side == 0? current.c100 - j: current.c100 + j;
					int newside = 1 - current.side;
					int newstep = current.step + 1;

					long ways = dp[current.c50][current.c100][current.side];
					if( current.side == 0 ){
						ways = ways * c[current.c50][i] % MODULAR;
						ways = ways * c[current.c100][j] % MODULAR;
					}
					else{
						ways = ways * c[c50 - current.c50][i] % MODULAR;
						ways = ways * c[c100 - current.c100][j] % MODULAR;
					}

					if( visited[newc50][newc100][newside] == -1 ){
						dp[newc50][newc100][newside] = ways;
						visited[newc50][newc100][newside] = newstep;
						queue.add( new State(newc50, newc100, newside, newstep) );
					}
					else if ( visited[newc50][newc100][newside] == newstep ){
						dp[newc50][newc100][newside] += ways;
						dp[newc50][newc100][newside] %= MODULAR;
					}
				}
			}

		}

		out.println( visited[0][0][1] );
		out.println( dp[0][0][1] );
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new C().run();
	}

	public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            out = new PrintWriter(System.out);
            solve();
            reader.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

}