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.util.*;
import java.io.*;
import java.text.*;
import java.util.stream.IntStream;

public class CF_1428_F{
    //SOLUTION BEGIN
    void pre() throws Exception{}
    void solve(int TC) throws Exception{
        int N = ni();
        String s = " "+n();

//        Random r = new Random();
//        int N = 100;
//        String s = " ";
//        for(int i = 0; i< N; i++)s += r.nextInt(2);

//        int[] start = new int[N];
        long[] F = new long[1+N];
        for(int i = 1; i<= N; i++)F[i] = F[i-1]+(i*(long)i+i)/2;

        int[][] comp = new int[N][];
        int[] sz = new int[N];
        int cnt = 0;
        for(int i = 1; i<= N; i++){
            if(s.charAt(i) == '1'){
                int end = i;
                while(end+1 <= N && s.charAt(1+end) == '1')end++;

                comp[cnt] = new int[]{i, end};
                sz[cnt] = end-i+1;
                cnt++;
                i = end;
            }
        }
//        for(int i = 0; i< cnt; i++)dbg(i, sz[i], comp[i][0], comp[i][1]);
        Integer[] ord = new Integer[cnt];
        for(int i = 0; i< cnt; i++)ord[i] = i;
        Arrays.sort(ord, (Integer i1, Integer i2) -> {
            if(sz[i1] != sz[i2])return Integer.compare(sz[i2], sz[i1]);
            return Integer.compare(comp[i1][0], comp[i2][0]);
        });

        long ans = 0;
        TreeSet<Integer> set = new TreeSet<>();
        for(int i = 0; i< cnt; i++){
            int ind = ord[i];
            int size = sz[ind];

            ans += F[sz[ind]]-sz[ind];
            Integer prev = set.floor(ind), nxt = set.ceiling(ind);
            if(prev == null)prev = 0;
            else prev = comp[prev][1]-size+1;
            if(nxt == null)nxt = N+1;
            else nxt = comp[nxt][0]+size;

            set.add(ind);
//            dbg(ans, sz[ind], comp[ind][0], comp[ind][1], prev, nxt, (nxt-comp[ind][1]), (comp[ind][0]-prev));
            ans += sz[ind] * (long)(nxt-comp[ind][1]) * (long)(comp[ind][0]-prev);
        }

        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i< cnt; i++){
            for(int size = 1; size < sz[i]; size++){
                while(!stack.isEmpty() && sz[stack.peek()] < size)stack.pop();

                int prev = 0;
                if(!stack.isEmpty()){
                    int ind = stack.peek();
                    prev = comp[ind][1]-size+1;
                }
//                dbg("p", i, size, prev, comp[i][0], (comp[i][0]-prev-1));
                ans += size * (long)(comp[i][0]-prev-1);
            }
            stack.push(i);
        }
        stack = new Stack<>();
        for(int i = cnt-1; i>= 0; i--){
            for(int size = 1; size < sz[i]; size++){
                while(!stack.isEmpty() && sz[stack.peek()] <= size)stack.pop();

                int nxt = N+1;
                if(!stack.isEmpty()){
                    int ind = stack.peek();
                    nxt = comp[ind][0]+size;
                }
//                dbg("n", i, nxt, comp[i][1]);
                ans += size * (long)(nxt-comp[i][1]-1);
            }
            stack.push(i);
        }
        pn(ans);


    }
    int longest(String s){
//        dbg(s);
        int ans = 0, cur = 0;
        for(int i = 0; i< s.length(); i++){
            if(s.charAt(i) == '1')cur++;
            else cur = 0;
            ans = Math.max(ans, cur);
        }
        return ans;
    }
    long eval(String s){
        long ans = 0;
        for(int i = 0; i< s.length(); i++)
            for(int j = i; j< s.length(); j++)
                ans += longest(s.substring(i, j+1));
            return ans;
    }

    class Node{
        long prod;
        Node le, ri;
        public Node(long x){
            prod = x; //EDIT
            le = null;ri = null;
        }
        public Node(Node le, Node ri){
            this.le = le;
            this.ri = ri;
            prod = le.prod * ri.prod; //EDIT
        }
    }
    long get(Node root, int ll, int rr, int l, int r){
        if(l == ll && r == rr)return root.prod;
        int mid = (ll+rr)>>1;
        if(r <= mid)return get(root.le, ll, mid, l, r);
        if(l > mid)return get(root.ri, mid+1, rr, l, r);
        return get(root.le, ll, mid, l, mid) + get(root.ri, mid+1, rr, mid+1, r); //EDIT
    }
    Node update(Node root, int ll, int rr, int p, long x){
        if(ll == rr)return new Node(x);//EDIT
        int mid = (ll+rr)>>1;
        if(p <= mid)return new Node(update(root.le, ll, mid, p, x), root.ri);
        else return new Node(root.le, update(root.ri, mid+1, rr, p, x));
    }
    Node build(int ll, int rr, int x){
        if(ll == rr)return new Node(x);//EDIT
        int mid = (ll+rr)>>1;
        return new Node(build(ll, mid, x), build(mid+1, rr, x));
    }

    //SOLUTION END
    void hold(boolean b)throws Exception{if(!b)throw new Exception("Hold right there, Sparky!");}
    void exit(boolean b){if(!b)System.exit(0);}
    static void dbg(Object... o){System.err.println(Arrays.deepToString(o));}
    final long IINF = (long)1e17;
    final int INF = (int)1e9+2;
    DecimalFormat df = new DecimalFormat("0.00000000000");
    double PI = 3.141592653589793238462643383279502884197169399, eps = 1e-8;
    static boolean multipleTC = false, memory = true, fileIO = false;
    FastReader in;PrintWriter out;
    void run() throws Exception{
        long ct = System.currentTimeMillis();
        if (fileIO) {
            in = new FastReader("");
            out = new PrintWriter("");
        } else {
            in = new FastReader();
            out = new PrintWriter(System.out);
        }
        //Solution Credits: Taranpreet Singh
        int T = multipleTC? ni():1;
        pre();
        for (int t = 1; t <= T; t++) solve(t);
        out.flush();
        out.close();
        System.err.println(System.currentTimeMillis() - ct);
    }
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new CF_1428_F().run();}catch(Exception e){e.printStackTrace();System.exit(1);}}}, "1", 1 << 28).start();
        else new CF_1428_F().run();
    }
    int[][] make(int n, int e, int[] from, int[] to, boolean f){
        int[][] g = new int[n][];int[]cnt = new int[n];
        for(int i = 0; i< e; i++){
            cnt[from[i]]++;
            if(f)cnt[to[i]]++;
        }
        for(int i = 0; i< n; i++)g[i] = new int[cnt[i]];
        for(int i = 0; i< e; i++){
            g[from[i]][--cnt[from[i]]] = to[i];
            if(f)g[to[i]][--cnt[to[i]]] = from[i];
        }
        return g;
    }
    int[][][] makeS(int n, int e, int[] from, int[] to, boolean f){
        int[][][] g = new int[n][][];int[]cnt = new int[n];
        for(int i = 0; i< e; i++){
            cnt[from[i]]++;
            if(f)cnt[to[i]]++;
        }
        for(int i = 0; i< n; i++)g[i] = new int[cnt[i]][];
        for(int i = 0; i< e; i++){
            g[from[i]][--cnt[from[i]]] = new int[]{to[i], i, 0};
            if(f)g[to[i]][--cnt[to[i]]] = new int[]{from[i], i, 1};
        }
        return g;
    }
    int find(int[] set, int u){return set[u] = (set[u] == u?u:find(set, set[u]));}
    int digit(long s){int ans = 0;while(s>0){s/=10;ans++;}return ans;}
    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));}
    void p(Object... o){for(Object oo:o)out.print(oo+" ");}
    void pn(Object... o){for(int i = 0; i< o.length; i++)out.print(o[i]+(i+1 < o.length?" ":"\n"));}
    void pni(Object... o){for(Object oo:o)out.print(oo+" ");out.println();out.flush();}
    String n()throws Exception{return in.next();}
    String nln()throws Exception{return in.nextLine();}
    int ni()throws Exception{return Integer.parseInt(in.next());}
    long nl()throws Exception{return Long.parseLong(in.next());}
    double nd()throws Exception{return Double.parseDouble(in.next());}

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

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

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

        String nextLine() throws Exception{
            String str;
            try{
                str = br.readLine();
            }catch (IOException e){
                throw new Exception(e.toString());
            }
            return str;
        }
    }
}