Zookeeper is buying a carton of fruit to feed his pet wabbit. The fruits are a sequence of apples and oranges, which is represented by a binary string s_1s_2… s_n of length n. 1 represents an apple and 0 represents an orange.

Since wabbit is allergic to eating oranges, Zookeeper would like to find the longest contiguous sequence of apples. Let f(l,r) be the longest contiguous sequence of apples in the substring s_{l}s_{l+1}… s_{r}. 

Help Zookeeper find ∑_{l=1}^{n} ∑_{r=l}^{n} f(l,r), or the sum of f across all substrings.

Input

The first line contains a single integer n (1 ≤ n ≤ 5 ⋅ 10^5).

The next line contains a binary string s of length n (s_i ∈ \{0,1\}) 

Output

Print a single integer: ∑_{l=1}^{n} ∑_{r=l}^{n} f(l,r). 

Examples

Input


4
0110


Output


12


Input


7
1101001


Output


30


Input


12
011100011100


Output


156

Note

In the first test, there are ten substrings. The list of them (we let [l,r] be the substring s_l s_{l+1} … s_r):

  * [1,1]: 0 
  * [1,2]: 01 
  * [1,3]: 011 
  * [1,4]: 0110 
  * [2,2]: 1 
  * [2,3]: 11 
  * [2,4]: 110 
  * [3,3]: 1 
  * [3,4]: 10 
  * [4,4]: 0 



The lengths of the longest contiguous sequence of ones in each of these ten substrings are 0,1,2,2,1,2,2,1,1,0 respectively. Hence, the answer is 0+1+2+2+1+2+2+1+1+0 = 12.
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.StringTokenizer;

public class Main {

static class BIT_RangeQueryPointUpdate {
	long[]bit;
	int n;
	public BIT_RangeQueryPointUpdate(int[]a, int n) {
		this.n = n;
		this.bit = new long[n+10];
	}
	public BIT_RangeQueryPointUpdate(int n) {
		this.n = n;
		this.bit = new long[n+10];
	}
	public void init_tree(int[]a) {
		Arrays.fill(this.bit, 0);
		for(int i=0; i<n; i++) {
			this.add(i, a[i]);
		}
	}
	public long sumQuery(int ind) {
		long sum = 0;
		ind++;
		for(; ind > 0; ind -= ind & (-ind)) {
			sum += bit[ind];
		}
		return sum;
	}
	public void add(int ind, int val) {
		ind++;
		for(; ind <= n; ind += ind & (-ind)) {
			bit[ind] += val;
		}
	}
	public long sumInRange(int l, int r) {
		return sumQuery(r) - sumQuery(l - 1);
	}
	
}


static class SegmentTree{
	
	int left, right;
	// lChild => tree[2*tn] , rChild => tree[2*tn+1]
	SegmentTree lChild, rChild; 
	long sum;
	int minimum;
	long lazyForSum = 0;
	int lazyForMin = 0;
	final int INF = (int)1e9;
	public SegmentTree(int[]arr, int left, int right) {
		this.left = left;
		this.right = right;
		if(left == right) { // LEAF NODE
			this.sum = arr[left];
			this.minimum = arr[left];
		}
		else {
			int mid = (left + right) >> 1;
			lChild = new SegmentTree(arr, left, mid);
			rChild = new SegmentTree(arr, mid + 1, right);
			recalculate();
		}
	}
	
	public void recalculate() { // BASICALLY DOING tree[tn] = tree[2*tn] + tree[2*tn]
		if(left == right)return;
		this.sum = lChild.sum + rChild.sum;
		this.minimum = Math.min(lChild.minimum, rChild.minimum);
	}
	
	public void pointUpdate(int index, int value) { // point update of type SET TO
		if(left == right) {
			this.sum = value;
			this.minimum = value;
		}else {
			if(index <= lChild.right) {
				lChild.pointUpdate(index, value);
			}else {
				rChild.pointUpdate(index, value);
			}
			recalculate();
		}
	}
	
	public void updateLazy() {
		if(this.lazyForSum != 0) {
			this.sum += 1L * (this.right - this.left + 1) * lazyForSum;
			if(left != right) {
				lChild.lazyForSum += this.lazyForSum;
				rChild.lazyForSum += this.lazyForSum;
			}
			this.lazyForSum = 0;
		}
		if(this.lazyForMin != INF) {
			this.minimum = Math.min(this.minimum, this.lazyForMin);
			if(left != right) {
				lChild.lazyForMin = Math.min(lChild.lazyForMin, this.lazyForMin);
				rChild.lazyForMin = Math.min(rChild.lazyForMin, this.lazyForMin);
			}
			this.lazyForMin = INF;
		}
	}
	public void rangeUpdate(int ql, int qr, int val) { // range update INCREMENT BY VALUE
		updateLazy();
		if(qr < this.left || ql > this.right) { // NO OVERLAP
			return;
		}
		if(ql <= this.left && qr >= this.right) { // COMPLETE OVERLAP
			this.sum += 1L * val * (this.right - this.left + 1);
			this.minimum += val;
			if(this.left != this.right) {
				lChild.lazyForSum += val;
				rChild.lazyForSum += val;
				lChild.lazyForMin += val;
				rChild.lazyForMin += val;
			}
			this.lazyForMin = INF;
			this.lazyForSum = 0;
			return;
		}
		lChild.rangeUpdate(ql, qr, val);
		rChild.rangeUpdate(ql, qr, val);
		recalculate();
	}

	public long sum(int ql, int qr) {
		updateLazy();
		if(ql <= this.left && qr >= this.right) { // COMPLETE OVERLAP
			return this.sum;
		}
		if(qr < this.left || ql > this.right) { // NO OVERLAP
			return 0;
		}
		return lChild.sum(ql, qr) + rChild.sum(ql, qr);
	}
	
}

	
public static void main(String[] args){
 
   new Thread(null, null, "Anshum Gupta", 99999999) {
        public void run() {
            try {
                solve();
            } catch(Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }.start();
}
 
static final long mxx = (long)(1e18 + 5), MOD = 998244353;
static final int mxN = (int)(1e6), mxV = (int)(1e6), log = 18, INF = (int)1e9;
static boolean[]vis;
static ArrayList<ArrayList<Integer>> adj = new ArrayList<ArrayList<Integer>>();
static int n, m, q, k;
static char[]str;

public static void solve() throws Exception {
	   // solve the problem here
		s = new MyScanner();
   		out = new PrintWriter(new BufferedOutputStream(System.out), true);
//	   		out = new PrintWriter("output.txt");
        int tc = 1;//s.nextInt();   	
    	for(int i=1; i<=tc; i++) {
//        	out.print("Case #" + i + ": ");
    		testcase();
    	}
          
        out.flush();
        out.close();
}



static void testcase() {
	n = s.nextInt();
	str = s.next().toCharArray();
	
	long ans = 0, cur = 0;
	
	// len is the current length of consecutive 1's
	int len = 0;
	
	// dp[i] => where we currently are and value of 
	long[] dp = new long[n + 1];
	
	for(int i = 0; i < n; i++) {
		
		if(str[i] == '0') {
			// increase counts for all 1's till len
			for(int j = 0; j <= len; j++) {
				dp[j]++;
			}
			len = 0;
		}else {
			len++; 
			cur += len + dp[len - 1];
			
			dp[len] += dp[len - 1]; 
			// increase value of dp[len]
			
			
			dp[len - 1] = 0;
		}
		
		ans += cur;
	}
	
	out.println(ans);
	
	
}



public static PrintWriter out;
public static MyScanner s;
static void shuffleArray(int[] a) {
	Random random = new Random();
	for (int i = a.length-1; i > 0; i--) {
		int index = random.nextInt(i + 1);
		int tmp = a[index];
		a[index] = a[i];
		a[i] = tmp;
	}
}
static void shuffleSort(int[] a) {
	shuffleArray(a);
	Arrays.parallelSort(a);
}
static class MyScanner {
 
    BufferedReader br;
    StringTokenizer st;
 
    public MyScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }
    public MyScanner(String fileName) {
    	try {
			br = new BufferedReader(new FileReader(fileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
    }
    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()); }
    int[] nextIntArray(int n){
    	int[]a = new int[n];
    	for(int i=0; i<n; i++) {
    		a[i] = this.nextInt();
    	}
    	return a;
    }
    long[] nextlongArray(int n) {
    	long[]a = new long[n];
    	for(int i=0; i<n; i++) {
    		a[i] = this.nextLong();
    	}
    	return a;
    }
    Integer[] nextIntegerArray(int n){
    	Integer[]a = new Integer[n];
    	for(int i=0; i<n; i++) {
    		a[i] = this.nextInt();
    	}
    	return a;
    }
    Long[] nextLongArray(int n) {
    	Long[]a = new Long[n];
    	for(int i=0; i<n; i++) {
    		a[i] = this.nextLong();
    	}
    	return a;
    }
    char[][] next2DCharArray(int n, int m){
    	char[][]arr = new char[n][m];
    	for(int i=0; i<n; i++) {
    		arr[i] = this.next().toCharArray();
    	}
    	return arr;
    }
    ArrayList<ArrayList<Integer>> readUndirectedUnweightedGraph(int n, int m) {
    	ArrayList<ArrayList<Integer>>adj = new ArrayList<ArrayList<Integer>>();
    	for(int i=0; i<=n; i++)adj.add(new ArrayList<Integer>());
    	for(int i=0; i<m; i++) {
    		int u = s.nextInt();
    		int v = s.nextInt();
    		adj.get(u).add(v);
    		adj.get(v).add(u);
    	}
    	return adj;
    }
    ArrayList<ArrayList<Integer>> readDirectedUnweightedGraph(int n, int m) {
    	ArrayList<ArrayList<Integer>>adj = new ArrayList<ArrayList<Integer>>();
    	for(int i=0; i<=n; i++)adj.add(new ArrayList<Integer>());
    	for(int i=0; i<m; i++) {
    		int u = s.nextInt();
    		int v = s.nextInt();
    		adj.get(u).add(v);
    	}
    	return adj;
    }
    String nextLine(){
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}
 
 
}