import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.BiFunction;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
//        var n = 200000;
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
//            a[i] = 41;
        }
        var t = System.nanoTime();
        writer.println(solve(n, a));
        debug("time:%.2f", (System.nanoTime() - t) / 1e9);

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
        var blockSize = (int) (Math.sqrt(n));
        int[] block;
        {
            var tmp = new ArrayList<Integer>();
            tmp.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            block = tmp.stream().mapToInt(i -> i).toArray();
        }
        var sqrt = new IntSqrt(becomeZero, 1, n) {
            @Override
            int reduce(int a, int b) {
                return Math.min(a, b);
            }

            @Override
            int reduceFrom() {
                return Integer.MAX_VALUE;
            }

            @Override
            boolean lastIndexKeepGoing(int i, int acc) {
                return i < acc;
            }
        };
        BiFunction<Integer, Integer, Boolean> keepGoing = (i, acc1) -> i < acc1;
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
//            var end = maxEnd(start, n, becomeZero, blockSize, block, sqrt);
            var end = sqrt.lastIndex(start, n);
//            debug("start=%d,end1=%d,end2=%d", start, end, sqrt.lastIndex(start, n, (i, acc1) -> i < acc1));
//            assert end == sqrt.lastIndex(start, n, (i, acc1) -> i < acc1);
            ans += end - start + 1;
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    static final boolean DEBUG = false;

    static void debug(String fmt, Object... args) {
        if (DEBUG) {
            System.out.println(String.format(fmt, args));
        }
    }

    static abstract class IntSqrt {
        final int n;
        final int[] a;
        final int[] blocks;
        final int blockSize;
        final int indexedFrom;

        IntSqrt(int[] a, int indexedFrom, int n) {
            this.n = n;
            this.indexedFrom = indexedFrom;
            this.a = a;
            blockSize = (int) Math.sqrt(n);
            var tmp = new ArrayList<Integer>();
            tmp.add(reduceFrom()); // place holder
            var acc = reduceFrom();
            for (var i = indexedFrom; i < indexedFrom + n; i++) {
                acc = reduce(acc, a[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(acc);
                    acc = reduceFrom();
                }
            }
            blocks = tmp.stream().mapToInt(i -> i).toArray();
        }

        abstract int reduce(int a, int b);

        abstract int reduceFrom();

        abstract boolean lastIndexKeepGoing(int i, int acc);

        int lastIndex(int start, int maxIndex) {
            var acc = reduceFrom();
            var i = start - 1;
            // before blocks, after this i should be at the block ending
            var whichBlock = (start - 1) / blockSize + 1;
            var blockEnd = whichBlock * blockSize;
            assert start <= blockEnd;
            if (i < blockEnd) {
                int newAcc;
                while (i + 1 <= blockEnd && i + 1 <= maxIndex
//                        && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                        && i + 1 < (newAcc = reduce(acc, a[i + 1]))) {
                    acc = newAcc;
                    i++;
                }
                if (i < blockEnd) {
                    return i;
                }
            }
            // during blocks
            var blockI = whichBlock;
            int newAcc;
            while (i + blockSize <= maxIndex
//                    && lastIndexKeepGoing(i + blockSize, (newAcc = reduce(acc, blocks[blockI + 1])))) {
                    && i + blockSize < (newAcc = reduce(acc, blocks[blockI + 1]))) {
                i += blockSize;
                blockI++;
                acc = newAcc;
            }
            // after block
            while (i + 1 <= maxIndex
//                    && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                    && i + 1 < (newAcc = reduce(acc, a[i + 1]))) {

                acc = newAcc;
                i++;
            }
            return i;
        }
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] block, IntSqrt sqrt) {
        assert start <= becomeZero[start];
        if (start == becomeZero[start]) {
            return start - 1;
        }
        var end = start;
        var min = becomeZero[start];
        int whichBlock = (end - 1) / blockSize + 1;
        var blockEnd = Math.min(n, whichBlock * blockSize);
        while (end < blockEnd) {
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        // now end is at the end of the nearest block
        var i = whichBlock;
        int newMin;
        int newEnd;
        while ((newEnd = end + blockSize) <= n && newEnd < (newMin = Math.min(block[i + 1], min))) {
            min = newMin;
            end = newEnd;
            i++;
        }
        while (end < n) {
            assert end <= (i + 1) * blockSize;
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
//        var n = 200000;
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
//            a[i] = 41;
        }
        var t = System.nanoTime();
        writer.println(solve(n, a));
        debug("time:%.2f", (System.nanoTime() - t) / 1e9);

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
        var blockSize = (int) (Math.sqrt(n));
        int[] block;
        {
            var tmp = new ArrayList<Integer>();
            tmp.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            block = tmp.stream().mapToInt(i -> i).toArray();
        }
        var sqrt = new IntSqrt(becomeZero, 1, n);
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
//            var end = maxEnd(start, n, becomeZero, blockSize, block, sqrt);
            var end = sqrt.lastIndex(start, n);
//            debug("start=%d,end1=%d,end2=%d", start, end, sqrt.lastIndex(start, n, (i, acc1) -> i < acc1));
//            assert end == sqrt.lastIndex(start, n, (i, acc1) -> i < acc1);
            ans += end - start + 1;
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    static final boolean DEBUG = false;

    static void debug(String fmt, Object... args) {
        if (DEBUG) {
            System.out.println(String.format(fmt, args));
        }
    }

    static class IntSqrt {
        final int n;
        final int[] a;
        final int[] blocks;
        final int blockSize;
        final int indexStart;
        final int indexEndEx;

        IntSqrt(int[] a, int indexStart, int n) {
            this.n = n;
            this.indexStart = indexStart;
            indexEndEx = indexStart + n;
            this.a = a;
            blockSize = (int) Math.sqrt(n);
            var tmp = new ArrayList<Integer>();
            {
                var i = indexStart;
                while (i-- > 0) {
                    tmp.add(reduceFrom()); // place holder
                }
            }
            var acc = reduceFrom();
            for (var i = indexStart; i < indexEndEx; i++) {
                acc = reduce(acc, a[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(acc);
                    acc = reduceFrom();
                }
            }
            blocks = tmp.stream().mapToInt(i -> i).toArray();
        }

        int reduce(int a, int b) {
//            throw new RuntimeException("还没有实现");
            return Math.min(a, b);
        }

        int reduceFrom() {
            //            throw new RuntimeException("还没有实现");
            return Integer.MAX_VALUE;
        }

        boolean lastIndexKeepGoing(int i, int acc) {
            //            throw new RuntimeException("还没有实现");
            return i < acc;
        }

        int lastIndex(int start, int maxIndex) {
            var acc = reduceFrom();
            var i = start - 1;
            // before blocks, after this i should be at the block ending
            var whichBlock = (start - 1) / blockSize + 1;
            var blockEnd = whichBlock * blockSize;
            assert start <= blockEnd;
            if (i < blockEnd) {
                int newAcc;
                while (i + 1 <= blockEnd && i + 1 <= maxIndex
                        && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                    acc = newAcc;
                    i++;
                }
                if (i < blockEnd) {
                    return i;
                }
            }
            // during blocks
            var blockI = whichBlock;
            int newAcc;
            while (i + blockSize <= maxIndex
                    && lastIndexKeepGoing(i + blockSize, (newAcc = reduce(acc, blocks[blockI + 1])))) {
                i += blockSize;
                blockI++;
                acc = newAcc;
            }
            // after block
            while (i + 1 <= maxIndex
                    && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                if (i + 1 >= newAcc) {
                    return i;
                }
                acc = newAcc;
                i++;
            }
            return i;
        }
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] block, IntSqrt sqrt) {
        assert start <= becomeZero[start];
        if (start == becomeZero[start]) {
            return start - 1;
        }
        var end = start;
        var min = becomeZero[start];
        int whichBlock = (end - 1) / blockSize + 1;
        var blockEnd = Math.min(n, whichBlock * blockSize);
        while (end < blockEnd) {
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        // now end is at the end of the nearest block
        var i = whichBlock;
        int newMin;
        int newEnd;
        while ((newEnd = end + blockSize) <= n && newEnd < (newMin = Math.min(block[i + 1], min))) {
            min = newMin;
            end = newEnd;
            i++;
        }
        while (end < n) {
            assert end <= (i + 1) * blockSize;
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.BiFunction;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
//        var n = 200000;
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
//            a[i] = 41;
        }
        var t = System.nanoTime();
        writer.println(solve(n, a));
        debug("time:%.2f", (System.nanoTime() - t) / 1e9);

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
        var blockSize = (int) (Math.sqrt(n));
        int[] block;
        {
            var tmp = new ArrayList<Integer>();
            tmp.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            block = tmp.stream().mapToInt(i -> i).toArray();
        }
        var sqrt = new IntSqrt(becomeZero, 1, n) {
            @Override
            int reduce(int a, int b) {
//                return Math.min(a, b);
                return a <= b ? a : b;
            }

            @Override
            int reduceFrom() {
                return Integer.MAX_VALUE;
            }

            @Override
            boolean lastIndexKeepGoing(int i, int acc) {
                return i < acc;
            }
        };
        BiFunction<Integer, Integer, Boolean> keepGoing = (i, acc1) -> i < acc1;
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
//            var end = maxEnd(start, n, becomeZero, blockSize, block, sqrt);
            var end = sqrt.lastIndex(start, n);
//            debug("start=%d,end1=%d,end2=%d", start, end, sqrt.lastIndex(start, n, (i, acc1) -> i < acc1));
//            assert end == sqrt.lastIndex(start, n, (i, acc1) -> i < acc1);
            ans += end - start + 1;
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    static final boolean DEBUG = false;

    static void debug(String fmt, Object... args) {
        if (DEBUG) {
            System.out.println(String.format(fmt, args));
        }
    }

    static abstract class IntSqrt {
        final int n;
        final int[] a;
        final int[] blocks;
        final int blockSize;
        final int indexedFrom;

        IntSqrt(int[] a, int indexedFrom, int n) {
            this.n = n;
            this.indexedFrom = indexedFrom;
            this.a = a;
            blockSize = (int) Math.sqrt(n);
            var tmp = new ArrayList<Integer>();
            tmp.add(reduceFrom()); // place holder
            var acc = reduceFrom();
            for (var i = indexedFrom; i < indexedFrom + n; i++) {
                acc = reduce(acc, a[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(acc);
                    acc = reduceFrom();
                }
            }
            blocks = tmp.stream().mapToInt(i -> i).toArray();
        }

        abstract int reduce(int a, int b);

        abstract int reduceFrom();

        abstract boolean lastIndexKeepGoing(int i, int acc);

        int lastIndex(int start, int maxIndex) {
            var acc = reduceFrom();
            var i = start - 1;
            // before blocks, after this i should be at the block ending
            var whichBlock = (start - 1) / blockSize + 1;
            var blockEnd = whichBlock * blockSize;
            assert start <= blockEnd;
            if (i < blockEnd) {
                int newAcc;
                while (i + 1 <= blockEnd && i + 1 <= maxIndex
//                        && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                        && i + 1 < (newAcc = reduce(acc, a[i + 1]))) {
                    acc = newAcc;
                    i++;
                }
                if (i < blockEnd) {
                    return i;
                }
            }
            // during blocks
            var blockI = whichBlock;
            int newAcc;
            while (i + blockSize <= maxIndex
//                    && lastIndexKeepGoing(i + blockSize, (newAcc = reduce(acc, blocks[blockI + 1])))) {
                    && i + blockSize < (newAcc = reduce(acc, blocks[blockI + 1]))) {
                i += blockSize;
                blockI++;
                acc = newAcc;
            }
            // after block
            while (i + 1 <= maxIndex
//                    && lastIndexKeepGoing(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                    && i + 1 < (newAcc = reduce(acc, a[i + 1]))) {

                acc = newAcc;
                i++;
            }
            return i;
        }
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] block, IntSqrt sqrt) {
        assert start <= becomeZero[start];
        if (start == becomeZero[start]) {
            return start - 1;
        }
        var end = start;
        var min = becomeZero[start];
        int whichBlock = (end - 1) / blockSize + 1;
        var blockEnd = Math.min(n, whichBlock * blockSize);
        while (end < blockEnd) {
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        // now end is at the end of the nearest block
        var i = whichBlock;
        int newMin;
        int newEnd;
        while ((newEnd = end + blockSize) <= n && newEnd < (newMin = Math.min(block[i + 1], min))) {
            min = newMin;
            end = newEnd;
            i++;
        }
        while (end < n) {
            assert end <= (i + 1) * blockSize;
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
        }
        writer.println(solve(n, a));

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
//        var minBz = new int[n + 2];
//        minBz[n + 1] = n + 1;
//        var accMinBz = n + 1;
        var blockSize = (int) (Math.sqrt(n));
        int[] sqrt;
        {
            var block = new ArrayList<Integer>();
            block.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    block.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            sqrt = block.stream().mapToInt(i -> i).toArray();
        }
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
            var end = maxEnd(start, n, becomeZero, blockSize, sqrt);
            ans += (long) end - start + 1;
//            accMinBz = Math.min(accMinBz, becomeZero[start]);
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] sqrt) {
        var end = start;
        var min = becomeZero[start];
        if (end >= min) {
            return end - 1;
        }
        end++;
        while (end <= n && end % blockSize != 0) {
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
            end++;
        }
        var i = end % blockSize;
        while (end + blockSize <= n && end < Math.min(sqrt[i + 1], min)) {
            min = Math.min(sqrt[i + 1], min);
            end += blockSize;
            i++;
        }
        while (end <= n) {
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
            end++;
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.BiFunction;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
        }
        writer.println(solve(n, a));

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
        var blockSize = (int) (Math.sqrt(n));
        int[] block;
        {
            var tmp = new ArrayList<Integer>();
            tmp.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            block = tmp.stream().mapToInt(i -> i).toArray();
        }
        var sqrt = new IntSqrt(becomeZero, 1, n) {
            @Override
            int reduce(int a, int b) {
                return Math.min(a, b);
            }

            @Override
            int reduceFrom() {
                return Integer.MAX_VALUE;
            }
        };
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
//            var end = maxEnd(start, n, becomeZero, blockSize, block, sqrt);
            var end = sqrt.lastIndex(start, n, (i, acc1) -> i < acc1);
//            debug("start=%d,end1=%d,end2=%d", start, end, sqrt.lastIndex(start, n, (i, acc1) -> i < acc1));
            assert end == sqrt.lastIndex(start, n, (i, acc1) -> i < acc1);
            ans += end - start + 1;
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    static void debug(String fmt, Object... args) {
        System.out.println(String.format(fmt, args));
    }

    static abstract class IntSqrt {
        final int n;
        final int[] a;
        final int[] blocks;
        final int blockSize;
        final int indexedFrom;

        IntSqrt(int[] a, int indexedFrom, int n) {
            this.n = n;
            this.indexedFrom = indexedFrom;
            this.a = a;
            blockSize = (int) Math.sqrt(n);
            var tmp = new ArrayList<Integer>();
            tmp.add(reduceFrom()); // place holder
            var acc = reduceFrom();
            for (var i = indexedFrom; i < indexedFrom + n; i++) {
                acc = reduce(acc, a[i]);
                if (i % blockSize == 0 || i == n) {
                    tmp.add(acc);
                    acc = reduceFrom();
                }
            }
            blocks = tmp.stream().mapToInt(i -> i).toArray();
        }

        abstract int reduce(int a, int b);

        abstract int reduceFrom();

        int lastIndex(int start, int maxIndex, BiFunction<Integer, Integer, Boolean> keepGoing) {
            var acc = reduceFrom();
            var i = start - 1;
            // before blocks, after this i should be at the block ending
            var whichBlock = (start - 1) / blockSize + 1;
            var blockEnd = whichBlock * blockSize;
            assert start <= blockEnd;
            if (i < blockEnd) {
                int newAcc;
                while (i + 1 <= blockEnd && i + 1 <= maxIndex
                        && keepGoing.apply(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                    acc = newAcc;
                    i++;
                }
                if (i < blockEnd) {
                    return i;
                }
            }
            // during blocks
            var blockI = whichBlock;
            int newAcc;
            while (i + blockSize <= maxIndex
                    && keepGoing.apply(i + blockSize, (newAcc = reduce(acc, blocks[blockI + 1])))) {
                i += blockSize;
                blockI++;
                acc = newAcc;
            }
            // after block
            while (i + 1 <= maxIndex
                    && keepGoing.apply(i + 1, (newAcc = reduce(acc, a[i + 1])))) {
                acc = newAcc;
                i++;
            }
            return i;
        }
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] block, IntSqrt sqrt) {
        assert start <= becomeZero[start];
        if (start == becomeZero[start]) {
            return start - 1;
        }
        var end = start;
        var min = becomeZero[start];
        int whichBlock = (end - 1) / blockSize + 1;
        var blockEnd = Math.min(n, whichBlock * blockSize);
        while (end < blockEnd) {
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        // now end is at the end of the nearest block
        var i = whichBlock;
        int newMin;
        int newEnd;
        while ((newEnd = end + blockSize) <= n && newEnd < (newMin = Math.min(block[i + 1], min))) {
            min = newMin;
            end = newEnd;
            i++;
        }
        while (end < n) {
            assert end <= (i + 1) * blockSize;
            end++;
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

public class C {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
        var a = new int[n + 1];
        for (var i = 1; i <= n; i++) {
            a[i] = scanner.nextInt();
        }
        writer.println(solve(n, a));

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static long solve(int n, int[] a) {
        return bf(n, a);
    }

    private static long bf(int n, int[] a) {
        var acc = new long[n + 1];
        acc[0] = 0;
        // 如果某个j使得acc[i-1]==acc[j]，那么其实end>=j都不会ok
        // 所以我们记住对于每个i，记住f[i]=min{j,acc[i-1]==acc[j],i<=j}。
        var becomeZero = new int[n + 1];
        Arrays.fill(becomeZero, n + 1);
        var last = new HashMap<Long, Integer>();
        last.put(0L, 0);
        for (var i = 1; i <= n; i++) {
            acc[i] = acc[i - 1] + a[i];
            if (a[i] == 0) {
                becomeZero[i] = i;
            } else {
                if (last.containsKey(acc[i])) {
                    becomeZero[last.get(acc[i]) + 1] = i;
                }
            }
            last.put(acc[i], i);
        }
        var ans = 0L;
//        var minBz = new int[n + 2];
//        minBz[n + 1] = n + 1;
//        var accMinBz = n + 1;
        var blockSize = (int) (Math.sqrt(n));
        int[] sqrt;
        {
            var block = new ArrayList<Integer>();
            block.add(-1); // place holder
            var blockMin = Integer.MAX_VALUE;
            for (var i = 1; i <= n; i++) {
                blockMin = Math.min(blockMin, becomeZero[i]);
                if (i % blockSize == 0 || i == n) {
                    block.add(blockMin);
                    blockMin = Integer.MAX_VALUE;
                }
            }
            sqrt = block.stream().mapToInt(i -> i).toArray();
        }
        for (var start = n; start >= 1; start--) {
            // find max end that end < g(start,end)=min{bz[start]..bz[end]}
            // for fixed start, g(start,end) decreases as end increasing
            var end = maxEnd(start, n, becomeZero, blockSize, sqrt);
            ans += end - start + 1;
//            accMinBz = Math.min(accMinBz, becomeZero[start]);
//            var maxEndEx = n + 1;
//            // maxEndEx decreases as end end increases
//            for (var end = start; end < maxEndEx; end++) {
//                maxEndEx = Math.min(maxEndEx, becomeZero[end]);
//                ans++;
////                if (ok(start, end, acc, becomeZero)) {
////                    ans++;
////                }
//            }
        }
        return ans;
    }

    private static int maxEnd(int start, int n, int[] becomeZero, int blockSize, int[] sqrt) {
        var end = start;
        var min = becomeZero[start];
        if (end >= min) {
            return end - 1;
        }
        end++;
        while (end <= n && end % blockSize != 0) {
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
            end++;
        }
        var i = end % blockSize;
        while (end + blockSize <= n && end < Math.min(sqrt[i + 1], min)) {
            min = Math.min(sqrt[i + 1], min);
            end += blockSize;
        }
        while (end <= n) {
            min = Math.min(min, becomeZero[end]);
            if (end >= min) {
                return end - 1;
            }
            end++;
        }
        return n;
    }

    private static boolean ok(int start, int end, long[] acc, int[] becomeZero) {
        for (var i = start; i <= end; i++) {
            assert end < becomeZero[i];
            if (end >= becomeZero[i]) {
                return false;
            }
        }
        return true;
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(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;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


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

public class Main {
	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);

	public static void main(String[] args) throws Exception {
		int n = sc.nextInt(), j = 1;
		long arr[] = new long[n + 1], ans = 0;
		TreeSet<Long> st = new TreeSet<>();
		for (int i = 1; i <= n; i++) {
			arr[i] = sc.nextInt() + arr[i - 1];
		}

		for(int i = 1; i <= n; i++) {
			j = Math.max(j,i);
			long cur = arr[i - 1];
			while(j <= n && arr[j] != cur && st.add(arr[j])) j++;
			ans += st.size();
			st.remove(arr[i]);
		}

		out.println(ans);
		out.close();
	}
}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

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

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

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

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

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

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

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// Java program to print all subarrays
// in the array which has sum 0
import java.io.*;
import java.util.*;

public class TaskC {

    public static void main(String[] args) {
        Utility.FastReader fr = new Utility.FastReader();
        int n = fr.nextInt();
        int[] arr = new int[n];
        HashMap<Long, Integer> hmap = new HashMap<>();
        hmap.put(0L, -1);
        long sum = 0; //stores prefix sum
        int latest = -1;
        long answer = 0;
        for(int i=0; i<n; ++i){
            arr[i] = fr.nextInt();
            sum += arr[i];
            if(hmap.containsKey(sum)){
                if(sum == 0 && hmap.get(0L) == -1){
                    latest = Math.max(latest, 0);
                }
                else{
                    latest = Math.max(latest, hmap.get(sum)+1);
                }
            }
            answer += i - latest;
            hmap.put(sum, i);
        }
        System.out.println(answer);
    }

    static class Utility {
        static 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;
            }
        }

        public static void main(String[] args) {
            FastReader s = new FastReader();
            int n = s.nextInt();
            int k = s.nextInt();
            int count = 0;
            while (n-- > 0) {
                int x = s.nextInt();
                if (x % k == 0)
                    count++;
            }
            System.out.println(count);
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// Java program to print all subarrays
// in the array which has sum 0
import java.io.*;
import java.util.*;

public class TaskC {
    // User defined pair class
    static class Pair
    {
        int first, second;
        Pair(int a, int b)
        {
            first = a;
            second = b;
        }
    }

    static class GFG
    {
        // Function to print all subarrays in the array which
        // has sum 0
        static ArrayList<Pair> findSubArrays(int[] arr, int n)
        {
            // create an empty map
            HashMap<Integer,ArrayList<Integer>> map = new HashMap<>();

            // create an empty vector of pairs to store
            // subarray starting and ending index
            ArrayList<Pair> out = new ArrayList<>();

            // Maintains sum of elements so far
            int sum = 0;

            for (int i = 0; i < n; i++)
            {
                // add current element to sum
                sum += arr[i];

                // if sum is 0, we found a subarray starting
                // from index 0 and ending at index i
                if (sum == 0)
                    out.add(new Pair(0, i));
                ArrayList<Integer> al = new ArrayList<>();

                // If sum already exists in the map there exists
                // at-least one subarray ending at index i with
                // 0 sum
                if (map.containsKey(sum))
                {
                    // map[sum] stores starting index of all subarrays
                    al = map.get(sum);
                    for (int it = 0; it < al.size(); it++)
                    {
                        out.add(new Pair(al.get(it) + 1, i));
                    }
                }
                al.add(i);
                map.put(sum, al);
            }
            return out;
        }

        // Utility function to print all subarrays with sum 0
        static void print(ArrayList<Pair> out)
        {
            for (int i = 0; i < out.size(); i++)
            {
                Pair p = out.get(i);
                System.out.println("Subarray found from Index "
                        + p.first + " to " + p.second);
            }
        }

    }

// This code is contributed by rachana soma

    static class ComparePair implements Comparator<Pair> {

        @Override
        public int compare(Pair o1, Pair o2) {
            if(o1.first == o2.first){
                return o1.second - o2.second;
            }
            return o1.first - o2.first;
        }
    }
    public static void main(String[] args) {
        Utility.FastReader fr = new Utility.FastReader();
        int n = fr.nextInt();
        int[] arr = new int[n];
        for(int i=0; i<n; ++i){
            arr[i] = fr.nextInt();
        }
        GFG g = new GFG();
        ArrayList<Pair> result = g.findSubArrays(arr, n);
        Collections.sort(result, new ComparePair());
        long res = 0;
        int prev_idx = 0;
        for(int i=0; i<result.size(); ++i){
            int first = result.get(i).first;
            int second = result.get(i).second;
            res += (second-prev_idx)*(second-prev_idx+1)/2 - (second-prev_idx);
            prev_idx = first+1;
        }
        int non_zero = 0;
        for(int i=0; i<n; ++i){
            if(arr[i] != 0){
                non_zero++;
            }
        }
        if(prev_idx < n-1){
            res += (n-prev_idx)*(n-prev_idx+1)/2 - (n-prev_idx);
        }
        res += non_zero;
        System.out.println(res);
    }

    static class Utility {
        static 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;
            }
        }

        public static void main(String[] args) {
            FastReader s = new FastReader();
            int n = s.nextInt();
            int k = s.nextInt();
            int count = 0;
            while (n-- > 0) {
                int x = s.nextInt();
                if (x % k == 0)
                    count++;
            }
            System.out.println(count);
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// Java program to print all subarrays
// in the array which has sum 0
import java.io.*;
import java.util.*;

public class TaskC {
    // User defined pair class
    static class Pair
    {
        int first, second;
        Pair(int a, int b)
        {
            first = a;
            second = b;
        }
    }

    static class GFG
    {
        // Function to print all subarrays in the array which
        // has sum 0
        static ArrayList<Pair> findSubArrays(int[] arr, int n)
        {
            // create an empty map
            HashMap<Integer,ArrayList<Integer>> map = new HashMap<>();

            // create an empty vector of pairs to store
            // subarray starting and ending index
            ArrayList<Pair> out = new ArrayList<>();

            // Maintains sum of elements so far
            int sum = 0;

            for (int i = 0; i < n; i++)
            {
                // add current element to sum
                sum += arr[i];

                // if sum is 0, we found a subarray starting
                // from index 0 and ending at index i
                if (sum == 0)
                    out.add(new Pair(0, i));
                ArrayList<Integer> al = new ArrayList<>();

                // If sum already exists in the map there exists
                // at-least one subarray ending at index i with
                // 0 sum
                if (map.containsKey(sum))
                {
                    // map[sum] stores starting index of all subarrays
                    al = map.get(sum);
                    for (int it = 0; it < al.size(); it++)
                    {
                        out.add(new Pair(al.get(it) + 1, i));
                    }
                }
                al.add(i);
                map.put(sum, al);
            }
            return out;
        }

        // Utility function to print all subarrays with sum 0
        static void print(ArrayList<Pair> out)
        {
            for (int i = 0; i < out.size(); i++)
            {
                Pair p = out.get(i);
                System.out.println("Subarray found from Index "
                        + p.first + " to " + p.second);
            }
        }

    }

// This code is contributed by rachana soma

    static class ComparePair implements Comparator<Pair> {

        @Override
        public int compare(Pair o1, Pair o2) {
            if(o1.first == o2.first){
                return o1.second - o2.second;
            }
            return o1.first - o2.first;
        }
    }
    public static void main(String[] args) {
        Utility.FastReader fr = new Utility.FastReader();
        int n = fr.nextInt();
        int[] arr = new int[n];
        for(int i=0; i<n; ++i){
            arr[i] = fr.nextInt();
        }
        GFG g = new GFG();
        ArrayList<Pair> result = g.findSubArrays(arr, n);
//        Collections.sort(result, new ComparePair());
        long res = 0;
        int prev_idx = 0;
        for(int i=0; i<result.size(); ++i){
            int first = result.get(i).first;
            int second = result.get(i).second;
            res += (second-prev_idx)*(second-prev_idx+1)/2 - (second-prev_idx);
            prev_idx = first+1;
        }
        int non_zero = 0;
        for(int i=0; i<n; ++i){
            if(arr[i] != 0){
                non_zero++;
            }
        }
        if(prev_idx < n-1){
            res += (n-prev_idx)*(n-prev_idx+1)/2 - (n-prev_idx);
        }
        res += non_zero;
        System.out.println(res);
    }

    static class Utility {
        static 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;
            }
        }

        public static void main(String[] args) {
            FastReader s = new FastReader();
            int n = s.nextInt();
            int k = s.nextInt();
            int count = 0;
            while (n-- > 0) {
                int x = s.nextInt();
                if (x % k == 0)
                    count++;
            }
            System.out.println(count);
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.StringTokenizer;
import java.util.Scanner;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.lang.Integer;
import java.util.HashMap;

public class Main {
    // driver function to test the above functions
    public static void main(String args[]) throws IOException {
        Reader.init(System.in);
        int n = Reader.nextInt();
        int[] arr =new int[n+1];
        long ans = 0;

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        arr[0] = 0;
        map.put(arr[0],0);
        for (int i=1; i<n+1; i++){
            arr[i] = arr[i-1]+Reader.nextInt();
            if (!map.containsKey(arr[i])){
                map.put(arr[i],i);
            }
        }
        int left_max = -1;
        for (int i=1; i<n+1; i++){
            int ind = map.get(arr[i]);
            if (ind<i&&ind+1>left_max){
                left_max=ind+1;
            }
            map.put(arr[i],i);
            if (left_max==-1){
                ans=ans+i;
            }
            else {
                ans=ans+(i-left_max);
            }
        }

        System.out.println(ans);
    }
}

class Node{
    char val;
    Node nxt = null;
    Node prev=null;

}

class solu{

}

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                    reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

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

    static String line() throws IOException {
        return reader.readLine();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.StringTokenizer;
import java.util.Scanner;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.lang.Integer;
import java.util.HashMap;

public class Main {
    // driver function to test the above functions
    public static void main(String args[]) throws IOException {
        Reader.init(System.in);
        int n = Reader.nextInt();
        long[] arr =new long[n+1];
        long ans = 0;

        HashMap<Long, Integer> map = new HashMap<Long, Integer>();
        arr[0] = 0;
        map.put(arr[0],0);
        for (int i=1; i<n+1; i++){
            arr[i] = arr[i-1]+Reader.nextInt();
            if (!map.containsKey(arr[i])){
                map.put(arr[i],i);
            }
        }
        int left_max = -1;
        for (int i=1; i<n+1; i++){
            int ind = map.get(arr[i]);
            if (ind<i&&ind+1>left_max){
                left_max=ind+1;
            }
            map.put(arr[i],i);
            if (left_max==-1){
                ans=ans+i;
            }
            else {
                ans=ans+(i-left_max);
            }
        }

        System.out.println(ans);
    }
}

class Node{
    char val;
    Node nxt = null;
    Node prev=null;

}

class solu{

}

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                    reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

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

    static String line() throws IOException {
        return reader.readLine();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.StringTokenizer;
import java.util.Scanner;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.lang.Integer;
import java.util.HashMap;

public class Main {
    // driver function to test the above functions
    public static void main(String args[]) throws IOException {
        Reader.init(System.in);
        int n = Reader.nextInt();
        int[] arr =new int[n+1];
        long ans = 0;

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        arr[0] = 0;
        map.put(arr[0],0);
        for (int i=1; i<n+1; i++){
            arr[i] = arr[i-1]+Reader.nextInt();
            if (!map.containsKey(arr[i])){
                map.put(arr[i],i);
            }
        }
        int left_max = -1;
        for (int i=1; i<n+1; i++){
            int ind = map.get(arr[i]);
            if (ind<i){
                left_max=ind+1;
                map.put(arr[i],i);
            }
            if (left_max==-1){
                ans=ans+i;
            }
            else {
                ans=ans+(i-left_max);
            }
        }

        System.out.println(ans);
    }
}

class Node{
    char val;
    Node nxt = null;
    Node prev=null;

}

class solu{

}

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                    reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

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

    static String line() throws IOException {
        return reader.readLine();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.StringTokenizer;
import java.util.Scanner;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.lang.Integer;
import java.util.HashMap;

public class Main {
    // driver function to test the above functions
    public static void main(String args[]) throws IOException {
        Reader.init(System.in);
        int n = Reader.nextInt();
        int[] arr =new int[n+1];
        long ans = 0;

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        arr[0] = 0;
        map.put(arr[0],0);
        for (int i=1; i<n+1; i++){
            arr[i] = arr[i-1]+Reader.nextInt();
            if (!map.containsKey(arr[i])){
                map.put(arr[i],i);
            }
        }
        int left_max = -1;
        for (int i=1; i<n+1; i++){
            int ind = map.get(arr[i]);
            if (ind<i){
                left_max=ind+1;
            }
            map.put(arr[i],i);
            if (left_max==-1){
                ans=ans+i;
            }
            else {
                ans=ans+(i-left_max);
            }
        }

        System.out.println(ans);
    }
}

class Node{
    char val;
    Node nxt = null;
    Node prev=null;

}

class solu{

}

/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                    reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

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

    static String line() throws IOException {
        return reader.readLine();
    }
}


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

public class Eugene {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(f.readLine());
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        long[] prefsum = new long[n + 1];
        int[] indexOfNextSame = new int[n + 1];
        Arrays.fill(indexOfNextSame, n + 1);
        HashMap<Long, Integer> indexOfLastOccurence = new HashMap<Long, Integer>();
        indexOfLastOccurence.put((long) 0, 0);
        for (int i = 1; i <= n; i++) {
            prefsum[i] = Integer.parseInt(tokenizer.nextToken()) + prefsum[i - 1];
            if (indexOfLastOccurence.containsKey(prefsum[i])) {
                indexOfNextSame[indexOfLastOccurence.get(prefsum[i])] = i;
            }
            indexOfLastOccurence.put(prefsum[i], i);
        }

        long numberOfGood = 0;

        for (int i = 0; i < n; i++) {
            numberOfGood += indexOfNextSame[i] - i - 1;
        }

        System.out.println(numberOfGood);
    }
}


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

public class Eugene {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(f.readLine());
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        long[] prefsum = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            prefsum[i] = Integer.parseInt(tokenizer.nextToken()) + prefsum[i - 1];
        }

        long numberOfGood = 0;

        HashMap<Long, Integer> numOf = new HashMap<Long, Integer>();
        int j = 0;
        for (int i = 0; i <= n; i++) {
            if (numOf.containsKey(prefsum[i])) {
                numOf.put(prefsum[i], numOf.get(prefsum[i]) + 1);
            } else {
                numOf.put(prefsum[i], 1);
            }

            while (numOf.get(prefsum[i]) > 1) {
                numOf.put(prefsum[j], numOf.get(prefsum[i]) - 1);
                j++;
            }

            numberOfGood += i - j;
        }

        System.out.println(numberOfGood);
    }
}


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

public class Eugene {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(f.readLine());
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        int[] prefsum = new int[n + 1];
        int[] indexOfNextSame = new int[n + 1];
        Arrays.fill(indexOfNextSame, n + 1);
        HashMap<Integer, Integer> indexOfLastOccurence = new HashMap<Integer, Integer>();
        indexOfLastOccurence.put(0, 0);
        for (int i = 1; i <= n; i++) {
            prefsum[i] = Integer.parseInt(tokenizer.nextToken()) + prefsum[i - 1];
            if (indexOfLastOccurence.containsKey(prefsum[i])) {
                indexOfNextSame[indexOfLastOccurence.get(prefsum[i])] = i;
            }
            indexOfLastOccurence.put(prefsum[i], i);
        }

        long numberOfGood = 0;

        for (int i = 0; i <= n; i++) {
            numberOfGood += indexOfNextSame[i] - i - 1;
        }

        System.out.println(numberOfGood);
    }
}


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

public class Eugene {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(f.readLine());
        StringTokenizer tokenizer = new StringTokenizer(f.readLine());
        long[] prefsum = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            prefsum[i] = Integer.parseInt(tokenizer.nextToken()) + prefsum[i - 1];
        }

        long numberOfGood = 0;

        HashMap<Long, Integer> numOf = new HashMap<Long, Integer>();
        int j = 0;
        for (int i = 0; i <= n; i++) {
            if (numOf.containsKey(prefsum[i])) {
                numOf.put(prefsum[i], numOf.get(prefsum[i]) + 1);
            } else {
                numOf.put(prefsum[i], 1);
            }

            while (numOf.get(prefsum[i]) > 1) {
                numOf.put(prefsum[j], numOf.get(prefsum[j]) - 1);
                j++;
            }

            numberOfGood += i - j;
        }

        System.out.println(numberOfGood);
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.io.IOException;
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;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CEugeneAndAnArray solver = new CEugeneAndAnArray();
        solver.solve(1, in, out);
        out.close();
    }

    static class CEugeneAndAnArray {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            int n = s.nextInt();
            long[] arr = s.nextLongArray(n);
            HashMap<Long, Long> map = new HashMap<>();
            map.put(0l, 0l);
            long[] sumTillNow = new long[n];
            for (int i = 0; i < n; i++) {
                sumTillNow[i] = i == 0 ? arr[i] : (sumTillNow[i - 1] + arr[i]);
            }

            long ans = ((long) (n) * (long) (n + 1l)) / 2l;
            long sum = 0l;
            int start = 0;
            for (int i = 0; i < n; i++) {
                sum += arr[i];
                if (map.containsKey(sum)) {
                    if (map.get(sum) == start) {
                        ans -= (n - (long) (i));
                        start++;
                    } else if (map.get(sum) > start) {
                        ans -= ((map.get(sum) + 1l - start) * (n - (long) (i)));
                        start = Math.toIntExact(map.get(sum) + 1l);
                    }
                }
                map.put(sum, (long) i + 1l);
            }

            out.println(ans);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 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 long[] nextLongArray(int n) {
            long[] array = new long[n];
            for (int i = 0; i < n; ++i) array[i] = nextLong();
            return array;
        }

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

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.io.IOException;
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;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CEugeneAndAnArray solver = new CEugeneAndAnArray();
        solver.solve(1, in, out);
        out.close();
    }

    static class CEugeneAndAnArray {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            int n = s.nextInt();
            int[] arr = s.nextIntArray(n);
            HashMap<Long, Long> map = new HashMap<>();
            map.put(0l, 1l);
            long ans = ((long) (n) * (long) (n + 1)) / 2l;
            long sum = 0l;
            for (int i = 0; i < n; i++) {
                sum += (long) (arr[i]);
                if (map.containsKey(sum)) {
                    ans -= ((n - i));
                }
                map.put(sum, map.getOrDefault(sum, 0l) + 1l);
            }

            out.println(ans);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 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 int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; ++i) array[i] = nextInt();
            return array;
        }

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

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.io.IOException;
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;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CEugeneAndAnArray solver = new CEugeneAndAnArray();
        solver.solve(1, in, out);
        out.close();
    }

    static class CEugeneAndAnArray {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            int n = s.nextInt();
            int[] arr = s.nextIntArray(n);
            HashMap<Long, Long> map = new HashMap<>();
            map.put(0l, 1l);
            long ans = ((long) (n) * (long) (n + 1)) / 2l;
            long sum = 0l;
            for (int i = 0; i < n; i++) {
                sum += (long) (arr[i]);
                if (map.containsKey(sum)) {
                    ans -= (map.get(sum) * (n - i));
                }
                map.put(sum, map.getOrDefault(sum, 0l) + 1l);
            }

            out.println(ans);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 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 int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; ++i) array[i] = nextInt();
            return array;
        }

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

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.io.IOException;
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;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CEugeneAndAnArray solver = new CEugeneAndAnArray();
        solver.solve(1, in, out);
        out.close();
    }

    static class CEugeneAndAnArray {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            int n = s.nextInt();
            long[] arr = s.nextLongArray(n);
            HashMap<Long, Long> map = new HashMap<>();
            map.put(0l, 1l);
            long ans = ((long) (n) * (long) (n + 1)) / 2l;
            long sum = 0l;
            for (int i = 0; i < n; i++) {
                sum += arr[i];
                if (map.containsKey(sum)) {
                    ans = ans - ((long) (n - i));
                }
                map.put(sum, map.getOrDefault(sum, 0l) + 1l);
            }

            out.println(ans);
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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 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 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 long[] nextLongArray(int n) {
            long[] array = new long[n];
            for (int i = 0; i < n; ++i) array[i] = nextLong();
            return array;
        }

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

        }

    }
}