You are given a binary string (i. e. a string consisting of characters 0 and/or 1) s of length n. You can perform the following operation with the string s at most once: choose a substring (a contiguous subsequence) of s having exactly k characters 1 in it, and shuffle it (reorder the characters in the substring as you wish).

Calculate the number of different strings which can be obtained from s by performing this operation at most once.

Input

The first line contains two integers n and k (2 ≤ n ≤ 5000; 0 ≤ k ≤ n).

The second line contains the string s of length n, consisting of characters 0 and/or 1.

Output

Print one integer — the number of different strings which can be obtained from s by performing the described operation at most once. Since the answer can be large, output it modulo 998244353.

Examples

Input


7 2
1100110


Output


16


Input


5 0
10010


Output


1


Input


8 1
10001000


Output


10


Input


10 8
0010011000


Output


1

Note

Some strings you can obtain in the first example:

  * to obtain 0110110, you can take the substring from the 1-st character to the 4-th character, which is 1100, and reorder its characters to get 0110; 
  * to obtain 1111000, you can take the substring from the 3-rd character to the 7-th character, which is 00110, and reorder its characters to get 11000; 
  * to obtain 1100101, you can take the substring from the 5-th character to the 7-th character, which is 110, and reorder its characters to get 101. 



In the second example, k = 0 so you can only choose the substrings consisting only of 0 characters. Reordering them doesn't change the string at all, so the only string you can obtain is 10010.
5 2
00011
 5 4
11011
 81 5
100000101000000011001101010100001010111000000110000000001000101101111000001000110
 4 3
1011
 47 25
11110011111001110100101010011000110111011011101
 291 159
011001110111110110001111000110001001111100010001011000110100110010001101100110111010101111100111110000110111001100111010001000011001010011011100101000101011010110010011010100100101111010111000001011110101001011101110100100111110011001101010001110110101010101100011101110111000011111011001110
 459 15
101010101010101010101010101010101010101010101111111111111111111111010101010101010101010101011111111111111111111101010101010101010101111111111111111111111101010101010101010111111111111111111111111101010101010101111111111111111111111111110110101010101011111111111111111111111111111001000111111111111111111111111111110000011111111111111111111111111111000001111111111111111111111111111100001111111111111111111111111111100111111111111111111111111111110111111111111
 105 58
110101000111100000011011011101110100001000110011010101100010111001011111010010111101011011010110011011110
 52 11
0110011111001000010000100010010001010100000100110100

10
 5
 187538
 4
 314445058
 1
 0
 132732930
 478323746


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

public class a729 {

	public static void main(String[] args) throws IOException {
   
		
//		try {
			
		BufferedWriter out = new BufferedWriter(
	            new OutputStreamWriter(System.out));
		BufferedReader br = new BufferedReader(
		        new InputStreamReader(System.in));
		PrintWriter pt = new PrintWriter(System.out);
		FastReader sc = new FastReader();
//		int t = sc.nextInt();
	
//for(int o = 0 ; o<t;o++){
//}
//     }catch(Exception e) {
//    	 return;
//     }
    
	int n = sc.nextInt();
	int k = sc.nextInt();
	String s = sc.next();
	int m = 998244353;
	long[]fac = new long[5002];
	fac[0] = 1;
	for(int i = 1 ; i<=5001;i++) {
		fac[i] = fac[i-1]*i%m;
	}
	int cnt = 0;
	for(int i = 0 ; i<n;i++) {
		if(s.charAt(i) == '1') {
			cnt++;
		}
	}
	
	if(k == 0) {
		System.out.println(1);
	}else if(k>cnt) {
		System.out.println(1);
	}else {
		long ans = 0;
		int c0 = 0;
		int c1 = 0;
		for(int i = 0 ; i<n;i++) {
			if(c1>k) {
				c1--;
				break;
			}
		if(s.charAt(i) == '1') {
			c1++;
		}else {
			c0++;
		}
		}
		int t = c1 + c0;
		long d = fac[c0]*fac[c1]%m;
		long nm = fac[t];
		long val = nm*modInverse(d, m)%m;
		ans = val;
		int p0 = c0;
		int p1 = c1;
		for(int i = 1 ; i<n;i++){
			
//			System.out.println(ans);
			if(s.charAt(i-1) == '1') {
				p1--;
			}else {
				p0--;
			}
			if(s.charAt(i-1)=='0') {
				continue;
			}
			int t1 = 0;
			int t0 = 0;
			for(int j = i ; j<n;j++) {
			if(t1>k) {
				t1--;
				break;
			}
				if(s.charAt(j) == '1') {
					t1++;
				}else{
					t0++;
				}
				
			}
		if(t1<k) {
			break;
		}
		
		long val1 = 0;
		long val2 = 0;
		long num1 = fac[t1 + t0];
		long dem1 = fac[t1]*fac[t0]%m;
//		System.out.println(p1 + " " + p0 + " " + t1 + " " + t0);
		
		val1 = (val1%m + num1*modInverse(dem1, m)%m)%m;
		val1 = (val1%m - 1%m + m)%m;
		
		long num2 = fac[p1 + p0];
		long dem2 = fac[p1]*fac[p0]%m;
		
		val2 = (val2%m + num2*modInverse(dem2, m)%m)%m;
		val2 = (val2%m - 1%m + m)%m;
		p1 = t1;
		p0 = t0;
		long diff = (val1%m- val2%m + m)%m;
//		System.out.println(diff + " " + i);
		
		ans = (ans%m + diff%m)%m;
		
		}
		
		System.out.println(ans);
		
		
		
	}
	
	
	
	
	}
     
     
//------------------------------------------------------------------------------------------------------------------------------------------------

	
	static int cntDivisors(int n)
    {
        int cnt = 0;
		for (int i=1; i<=Math.sqrt(n); i++)
        {
            if (n%i==0)
            {
                if (n/i == i)
                	cnt++;
                	
                else 
                	cnt+=2;
            }
        }
    
    return cnt;
    }
	
	
	
	public static long findgcd(long[] arr,int v) {
		int n = arr.length;
		long g = arr[v];
		for(int i = v ; i<n;i+=2) {
			g = gcd(g, arr[i]);
		}
		return g;
	}
	
	

	public static long ncr(long[] fac, int n , int r , long m) {
		return fac[n]*(modInverse(fac[r], m))%m *(modInverse(fac[n-r], m))%m; 
	}
	
	
	public static void build(int [][] seg,char []arr,int idx, int lo , int hi) {
	if(lo == hi) {
//		seg[idx] = arr[lo];
		seg[idx][(int)arr[lo]-'a'] = 1;
		
		return;
	}
	int mid = (lo + hi)/2;
build(seg,arr,2*idx+1, lo, mid);
build(seg,arr,idx*2+2, mid +1, hi);
//seg[idx] = Math.min(seg[2*idx+1],seg[2*idx+2]);
for(int i = 0 ; i<27;i++) {
	seg[idx][i] = seg[2*idx+1][i] + seg[2*idx + 2][i];
}
	}
//for f/inding minimum in range 
public static void query(int[][]seg,int[]ans,int idx , int lo , int hi , int l , int r) {
	if(lo>=l && hi<=r) {
		for(int i = 0 ; i<27;i++) {
			ans[i]+= seg[idx][i];
		}
		return ;
	}
if(hi<l || lo>r) {
	return;
}
int mid = (lo + hi)/2;
query(seg,ans,idx*2 +1, lo, mid, l, r);
query(seg,ans,idx*2 + 2, mid + 1, hi, l, r);
//return Math.min(left, right);
}
//// for sum
//
public static void update(int[][]seg,char[]arr,int idx, int lo , int hi , int node , char val) {
if(lo == hi) {
//	seg[idx] += val;
seg[idx][val-'a']++;
seg[idx][arr[node]-'a']--;

}else {
int mid = (lo + hi )/2;
if(node<=mid && node>=lo) {
update(seg,arr, idx * 2 +1, lo, mid, node, val);
}else {
update(seg,arr, idx*2 + 2, mid + 1, hi, node, val);
}
//seg[idx] = seg[idx*2 + 1] + seg[idx*2 + 2];
for(int i = 0 ; i<27;i++) {
	seg[idx][i] = seg[2*idx+1][i] + seg[2*idx + 2][i];
}
}

}
	
	
	
	
	
	
	public static int lower_bound(int array[], int low, int high, int key){
	// Base Case
	if (low > high) {
	return low;
	}

	// Find the middle index
	int mid = low + (high - low) / 2;

	// If key is lesser than or equal to
	// array[mid] , then search
	// in left subarray
	if (key <= array[mid]) {

	return lower_bound(array, low,
	            mid - 1, key);
	}

	// If key is greater than array[mid],
	// then find in right subarray
	return lower_bound(array, mid + 1, high,
	        key);
	}
	
	public static int upper_bound(int arr[], int low,
            int high, int key){
// Base Case
if (low > high || low == arr.length)
return low;

// Find the value of middle index
int mid = low + (high - low) / 2;

// If key is greater than or equal
// to array[mid], then find in
// right subarray
if (key >= arr[mid]) {
return upper_bound(arr, mid + 1, high,
                key);
}

// If key is less than array[mid],
// then find in left subarray
return upper_bound(arr, low, mid - 1,
            key);
}

//	-----------------------------------------------------------------------------------------------------------------------------------------------
	public static long gcd(long a, long b){
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
//--------------------------------------------------------------------------------------------------------------------------------------------------------
	public static long modInverse(long a, long m){
        long m0 = m;
        long y = 0, x = 1;
 
        if (m == 1)
            return 0;
 
        while (a > 1) {
            // q is quotient
            long q = a / m;
 
            long t = m;
 
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
 
            // Update x and y
            y = x - q * y;
            x = t;
        }
 
        // Make x positive
        if (x < 0)
            x += m0;
 
        return x;
    }

		

//-----------------------------------------------------------------------------------------------------------------------------------

	//segment tree
	//for finding minimum in range 
//	public static void build(int [] seg,int []arr,int idx, int lo , int hi) {
//		if(lo == hi) {
//			seg[idx] = arr[lo];
//			return;
//		}
//		int mid = (lo + hi)/2;
//	build(seg,arr,2*idx+1, lo, mid);
//	build(seg,arr,idx*2+2, mid +1, hi);
//	seg[idx] = Math.min(seg[2*idx+1],seg[2*idx+2]);
//	}
////for finding minimum in range 
//public static int query(int[]seg,int idx , int lo , int hi , int l , int r) {
//		if(lo>=l && hi<=r) {
//			return seg[idx];
//		}
//	if(hi<l || lo>r) {
//		return Integer.MAX_VALUE;
//	}
//	int mid = (lo + hi)/2;
//	int left = query(seg,idx*2 +1, lo, mid, l, r);
//	int right = query(seg,idx*2 + 2, mid + 1, hi, l, r);
//	return Math.min(left, right);
//}
//	// for sum
//
//public static void update(int[]seg,int idx, int lo , int hi , int node , int val) {
//	if(lo == hi) {
//		seg[idx] += val;
//	}else {
//int mid = (lo + hi )/2;
//if(node<=mid && node>=lo) {
//	update(seg, idx * 2 +1, lo, mid, node, val);
//}else {
//	update(seg, idx*2 + 2, mid + 1, hi, node, val);
//}
//seg[idx] = seg[idx*2 + 1] + seg[idx*2 + 2];
//
//}

//}
//---------------------------------------------------------------------------------------------------------------------------------------


	static void shuffleArray(long[] ar)
	  {
	    // If running on Java 6 or older, use `new Random()` on RHS here
	    Random rnd = ThreadLocalRandom.current();
	    for (int i = ar.length - 1; i > 0; i--)
	    {
	      int index = rnd.nextInt(i + 1);
	      // Simple swap
	      long a = ar[index];
	      ar[index] = ar[i];
	      ar[i] = a;
	    }
	  }
//-----------------------------------------------------------------------------------------------------------------------------------------------------------

}


class FastReader {
    BufferedReader br;
    StringTokenizer st;

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

    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;
    }
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
class SegmentTree{
	
int n;
	public SegmentTree(int[] arr,int n) {
		this.arr = arr;
		this.n = n;
	}
	int[] arr = new int[n];
//	int n = arr.length;
	int[] seg = new int[4*n];
	void build(int idx, int lo , int hi) {
		if(lo == hi) {
			seg[idx] = arr[lo];
			return;
		}
		int mid = (lo + hi)/2;
	build(2*idx+1, lo, mid);
	build(idx*2+2, mid +1, hi);
	seg[idx] = Math.min(seg[2*idx+1],seg[2*idx+2]);
	}
	int query(int idx , int lo , int hi , int l , int r) {
		if(lo<=l && hi>=r) {
			return seg[idx];
		}
	if(hi<l || lo>r) {
		return Integer.MAX_VALUE;
	}
	int mid = (lo + hi)/2;
	int left = query(idx*2 +1, lo, mid, l, r);
	int right = query(idx*2 + 2, mid + 1, hi, l, r);
	return Math.min(left, right);
	}
	
	
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------
class coup{
	char a; 
	int b;
	public coup(char a , int b) {
		this.a = a;
		this.b = b;
	}
}

class trip{
	int a , b, c;
	public trip(int a , int b, int c) {
		this.a = a;
		this.b = b;
		this.c = c;
	}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
