import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {
	static ArrayList<Edge> adj[];
	static PrintWriter out = new PrintWriter(System.out);
	public static long mod;

	static int [][]notmemo;
	static int k;
	static int a[];
	static int b[];
	static int m;
	static char c[];

	static class Pair implements Comparable<Pair>{
    	int x;
    	int y;
    	public Pair(int a,int b) {
		x=a;
		y=b;

    	}
		@Override
		public int compareTo(Pair o) {
			if(x!=o.x)
			return x-o.x;
			return y-o.y;
		}

    }
    static Pair s1[];
    static int s[];
    static ArrayList<Pair> adjlist[];
	private static HashSet<Integer> set1[];
	public static void main(String args[]) throws IOException {
		Scanner sc = new Scanner(System.in);
	int n=sc.nextInt();
	int a[]=new int[n];
	for (int i = 0; i < a.length; i++) {
		a[i]=sc.nextInt();
	}
	int cumsum[]=new int[n+1];
	cumsum[0]=0;
	for (int i = 1; i < cumsum.length; i++) {
		cumsum[i]=cumsum[i-1]+a[i-1];
	}
	HashMap<Long,Integer> map=new HashMap<>();
	long cursum=0;
	int start=0;
	long count=0;
	for (int i = 0; i < a.length; i++) {
		if(map.containsKey(cursum+a[i])) {
			int idx=map.get(cursum+a[i]);
			map.clear();
			//map.put(0*1l,0);
			cursum=0;
			long len=i-start;
			if(len==0) {
				len=1;
			}
			long len2=i-idx-1;

	//		System.out.println("hi"+" "+i+" "+start+" "+idx);
			count+=(((len)*(len+1))/2);
		//	System.out.println(count);
			count-=(((len2)*(len2+1))/2);
			//System.out.println(count);
			start=idx+1;
		i=idx;
		}
		else if(cursum+a[i]==0) {
			//System.out.println(i+" "+start);
			count+=i-start;
			start++;
			i=start-1;
			//System.out.println(i+" "+start);

			map.clear();
			cursum=0;
		}
		else {
			cursum+=a[i];
			map.put(cursum,i+1);
		}
	}
//	System.out.println(start+" "+count);
	long len=n-start;
//	System.out.println(len+" h"+" "+count);
	count+=(((len)*(len+1))/2);

	System.out.println(count);
	}
    // with sum exactly equal to k.
    static int findSubarraySum(int arr[], int n, int sum)
    {
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        HashMap <Integer, Integer> prevSum = new HashMap<>();

        int res = 0;

        // Sum of elements so far.
        int currsum = 0;

        for (int i = 0; i < n; i++) {

            // Add current element to sum so far.
            currsum += arr[i];

            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum != 0)
                res++;

            // currsum exceeds given sum by currsum
            //  - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.containsKey(currsum - arr[i]))
                res += prevSum.get(currsum - arr[i]);

            // Add currsum value to count of
            // different values of sum.
            Integer count = prevSum.get(currsum);
            if (count == null)
                prevSum.put(currsum, 1);
            else
                prevSum.put(currsum, count+1);
        }

        return res;
    }
	public static int countvowels() {
		int count=0;
		for (int i = 0; i < c.length; i++) {
			if(c[i]=='o'||c[i]=='e'||c[i]=='a'||c[i]=='i'||c[i]=='u') {
				count++;
			}
		}
		return count;
	}
	public static  char lastvowel() {
		for (int i = c.length-1; i>=0; i--) {
			if(c[i]=='o'||c[i]=='e'||c[i]=='a'||c[i]=='i'||c[i]=='u') {
		return c[i];
			}
		}
		return 'a';
	}
	static class pp{
		String ss;
		String mm;
		public pp(String a,String b) {
		ss=a;
		mm=b;
		}
	}
	static class Tri implements Comparable<Tri>{
		String s;
		int numofvow;
		char lastchar;
	public	Tri(String m,int a,char c1){
			s=m;
			numofvow=a;
			lastchar=c1;

		}
	public int compareTo(Tri t) {
		if (numofvow == t.numofvow)
			return lastchar - t.lastchar;
		return numofvow - t.numofvow;
	}

	}
	static boolean dfs(int u, int cost) {
		boolean f=false;
		vis[u]=true;
		for(Edge p:adj[u]) {
			if(!vis[p.node]) {
				f|=dfs(p.node,(int) p.cost);
			}
		}
		if (cost == 2&&!f) {
				set.add(u + 1);
				return true;
		}
			return f;

	}
	static int min(int i,int last) {
		if(i==a.length)
			return 0;
		int take=0;
		if(gcd(a[i],last)>1||i==0) {
			take=Math.max(take,1+min(i+1,a[i]));
		}
	 take=Math.max(take,min(i+1,last));

		return b[i]=take;
	}

	private static boolean check(String s) {
		char c1[]=s.toCharArray();
		for (int i = 0; i < c1.length; i++) {
			if(c[i]>c1[i]) {
				return true;
			}
			 if(c[i]<c1[i])
				return false;
		}
		return true;
	}

	static long dijkstra(int S, int T)	//O(E log E)
	{
		long[] dist = new long[V];
		Arrays.fill(dist, (int) 1e9);
		PriorityQueue<Edge> pq = new PriorityQueue<Edge>();
		dist[S] = 0;
		pq.add(new Edge(S, 0));						//may add more in case of MSSP (Mult-Source)
		while(!pq.isEmpty())
		{
			Edge cur = pq.remove();
			if(cur.node == T)						//remove if all computations are needed
				return dist[T];
			if(cur.cost > dist[cur.node])			//lazy deletion
				continue;
			for(Edge nxt: adj[cur.node])
				if(cur.cost + nxt.cost < dist[nxt.node])
					pq.add(new Edge(nxt.node, dist[nxt.node] = cur.cost + nxt.cost ));
		}
		return -1;
	}
	static class Edge implements Comparable<Edge>
	{
		int node;long cost;

		Edge(int a, long b) { node = a;	cost = b; }

		public int compareTo(Edge e){ return Long.compare(cost,e.cost);	}
	}

    static int dp(int idx,int state) {
      if(idx==n) {
    	  return 0;
      }
      if(notmemo[idx][state]!=-1) {
    	  return notmemo[idx][state];
      }
     int take=0; int leave=0;int leaveall=0;
      if(a[idx]==1&&(state==1||state==0)) {
    	take=1+dp(idx+1,1);
      }
      if(a[idx]==0&&state==0) {
    	 leave=1+dp(idx+1,state);
      }
      leaveall=dp(idx+1,state);

      return notmemo[idx][state]=Math.max(take,Math.max(leaveall,leave));
    }
        static void sieve(int N)	// O(N log log N)
	{
		isComposite = new int[N+1];
		isComposite[0] = isComposite[1] = 1;			// 0 indicates a prime number
		primes = new ArrayList<Integer>();

		for (int i = 2; i <= N; ++i) 					//can loop till i*i <= N if primes array is not needed O(N log log sqrt(N))
			if (isComposite[i] == 0) 					//can loop in 2 and odd integers for slightly better performance
			{
				primes.add(i);
				if(1l * i * i <= N)
					for (int j = i * i; j <= N; j += i)	// j = i * 2 will not affect performance too much, may alter in modified sieve
						isComposite[j] = 1;
			}
	}
    static TreeSet<Integer> factors;
    static ArrayList<Integer> primeFactors(int N)		// O(sqrt(N) / ln sqrt(N))
	{
		ArrayList<Integer> factors = new ArrayList<Integer>();		//take abs(N) in case of -ve integers
		int idx = 0, p = primes.get(idx);

		while(1l*p * p <= N)
		{
			while(N % p == 0) { factors.add(p); N /= p; }
			p = primes.get(++idx);
		}

		if(N != 1)						// last prime factor may be > sqrt(N)
			factors.add(N);				// for integers whose largest prime factor has a power of 1
		return factors;
	}

    static String y;
    	static int nomnom[];
	static long fac[];

	static class book implements Comparable<book> {
		int idx;
		long score;

		public book(int i, long s) {
			idx = i;
			score = s;
		}

		public int compareTo(book o) {
			return (int) (o.score - score);
		}
	}

	static class library implements Comparable<library> {
		int numofbooks;
		int signup;
		int shiprate;
		int idx;

		public library(int a, int b, int c, int idx) {
			numofbooks = a;
			signup = b;
			shiprate = c;
			this.idx = idx;
		}

		@Override
		public int compareTo(library o) {
		if(signup==o.signup) {
			  return o.numofbooks-numofbooks;
		}
		return signup - o.signup;

		}
	}

	static boolean isOn(int S, int j) {
		return (S & 1 << j) != 0;
	}

	static boolean f = true;

	static class SegmentTree { // 1-based DS, OOP

		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;

		SegmentTree(int[] in) {
			array = in;
			N = in.length - 1;
			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N << 1];
			//build(1, 1, N);
		}

		void build(int node, int b, int e) // O(n)
		{
			if (b == e)
				sTree[node] = array[b];
			else {
				int mid = b + e >> 1;
				build(node << 1, b, mid);
				build(node << 1 | 1, mid + 1, e);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}
		}

		void update_point(int index, int val) // O(log n)
		{
			index += N - 1;
			sTree[index] = val;
			while(index>1)
			{
				index >>= 1;
				sTree[index] = Math.max(sTree[index<<1] ,sTree[index<<1|1]);
			}
		}

		void update_range(int i, int j, int val) // O(log n)
		{
			update_range(1, 1, N, i, j, val);
		}

		void update_range(int node, int b, int e, int i, int j, int val) {
			if (i > e || j < b)
				return;
			if (b >= i && e <= j) {
				sTree[node] += (e - b + 1) * val;
				lazy[node] += val;
			} else {
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node << 1, b, mid, i, j, val);
				update_range(node << 1 | 1, mid + 1, e, i, j, val);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}

		}

		void propagate(int node, int b, int mid, int e) {
			lazy[node << 1] += lazy[node];
			lazy[node << 1 | 1] += lazy[node];
			sTree[node << 1] += (mid - b + 1) * lazy[node];
			sTree[node << 1 | 1] += (e - mid) * lazy[node];
			lazy[node] = 0;
		}

		int query(int i, int j) {
			return query(1, 1, N, i, j);
		}

		int query(int node, int b, int e, int i, int j) // O(log n)
		{
			if (i > e || j < b)
				return 0;
			if (b >= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			// propagate(node, b, mid, e);
			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
			return Math.max(q1,q2);

		}
	}

	static int memo[];

	static class UnionFind {
		int[] p, rank, setSize;
		int numSets;
		int max[];

		public UnionFind(int N) {
			p = new int[numSets = N];
			rank = new int[N];
			setSize = new int[N];
			for (int i = 0; i < N; i++) {
				p[i] = i;
				setSize[i] = 1;
			}
		}

		public int findSet(int i) {
			return p[i] == i ? i : (p[i] = findSet(p[i]));
		}

		public boolean isSameSet(int i, int j) {
			return findSet(i) == findSet(j);
		}

		public void unionSet(int i, int j) {
			if (isSameSet(i, j))
				return;
			numSets--;
			int x = findSet(i), y = findSet(j);
			if (rank[x] > rank[y]) {
				p[y] = x;
				setSize[x] += setSize[y];

			} else {
				p[x] = y;
				setSize[y] += setSize[x];
				if (rank[x] == rank[y])
					rank[y]++;

			}
		}

		public int numDisjointSets() {
			return numSets;
		}

		public int sizeOfSet(int i) {
			return setSize[findSet(i)];
		}
	}

	/**
	 * private static void trace(int i, int time) { if(i==n) return;
	 *
	 *
	 * long ans=dp(i,time);
	 * if(time+a[i].t<a[i].burn&&(ans==dp(i+1,time+a[i].t)+a[i].cost)) {
	 *
	 * trace(i+1, time+a[i].t);
	 *
	 * l1.add(a[i].idx); return; } trace(i+1,time);
	 *
	 * }
	 **/

	static class incpair implements Comparable<incpair> {
		int a;
		long b;
		int idx;

		incpair(int a, long dirg, int i) {
			this.a = a;
			b = dirg;
			idx = i;
		}

		public int compareTo(incpair e) {
			return (int) (b - e.b);
		}
	}

	static class decpair implements Comparable<decpair> {
		int a;
		long b;
		int idx;

		decpair(int a, long dirg, int i) {
			this.a = a;
			b = dirg;
			idx = i;
		}

		public int compareTo(decpair e) {
			return (int) (e.b - b);
		}
	}

	static long allpowers[];

	static class Quad implements Comparable<Quad> {
		int u;
		int v;
		char state;
		int turns;

		public Quad(int i, int j, char c, int k) {
			u = i;
			v = j;
			state = c;
			turns = k;
		}

		public int compareTo(Quad e) {
			return (int) (turns - e.turns);
		}

	}

	static long dirg[][];
	static Edge[] driver;

	static int n;

	static long manhatandistance(long x, long x2, long y, long y2) {
		return Math.abs(x - x2) + Math.abs(y - y2);
	}

	static long fib[];

	static long fib(int n) {
		if (n == 1 || n == 0) {
			return 1;
		}
		if (fib[n] != -1) {
			return fib[n];
		} else
			return fib[n] = ((fib(n - 2) % mod + fib(n - 1) % mod) % mod);
	}

	static class Point  implements Comparable<Point>{
		long x, y;

		Point(long counth, long counts) {
			x = counth;
			y = counts;
		}

		@Override
		public int compareTo(Point p )
		{
			return Long.compare(p.y*1l*x, p.x*1l*y);
		}

	}

	static long[][] comb;

	static class Triple implements Comparable<Triple> {

		int l;
		int r;
		long cost;
		int idx;

		public Triple(int a, int b, long l1, int l2) {
			l = a;
			r = b;
			cost = l1;
			idx = l2;
		}

		public int compareTo(Triple x) {
			if (l != x.l || idx == x.idx)
				return l - x.l;
			return -idx;
		}

	}

	static TreeSet<Long> primeFactors(long N) // O(sqrt(N) / ln sqrt(N))
	{
		TreeSet<Long> factors = new TreeSet<Long>(); // take abs(N) in case of -ve integers
		int idx = 0, p = primes.get(idx);

		while (p * p <= N) {
			while (N % p == 0) {
				factors.add((long) p);
				N /= p;
			}
			if (primes.size() > idx + 1)
				p = primes.get(++idx);
			else
				break;
		}

		if (N != 1) // last prime factor may be > sqrt(N)
			factors.add(N); // for integers whose largest prime factor has a power of 1
		return factors;
	}

	static boolean visited[];

	/**
	 * static int bfs(int s) { Queue<Integer> q = new LinkedList<Integer>();
	 * q.add(s); int count=0; int maxcost=0; int dist[]=new int[n]; dist[s]=0;
	 * while(!q.isEmpty()) {
	 *
	 * int u = q.remove(); if(dist[u]==k) { break; } for(Pair v: adj[u]) {
	 * maxcost=Math.max(maxcost, v.cost);
	 *
	 *
	 *
	 * if(!visited[v.v]) {
	 *
	 * visited[v.v]=true; q.add(v.v); dist[v.v]=dist[u]+1; maxcost=Math.max(maxcost,
	 * v.cost); } }
	 *
	 * } return maxcost; }
	 **/
	public static boolean FindAllElements(int n, int k) {
		int sum = k;
		int[] A = new int[k];
		Arrays.fill(A, 0, k, 1);

		for (int i = k - 1; i >= 0; --i) {

			while (sum + A[i] <= n) {

				sum += A[i];
				A[i] *= 2;
			}
		}
		if (sum == n) {
			return true;
		} else
			return false;
	}

	static boolean[] vis2;

	static boolean f2 = false;

	static long[][] matMul(long[][] a2, long[][] b, int p, int q, int r) // C(p x r) = A(p x q) x (q x r) -- O(p x q x
																			// r)
	{
		long[][] C = new long[p][r];
		for (int i = 0; i < p; ++i) {
			for (int j = 0; j < r; ++j) {
				for (int k = 0; k < q; ++k) {
					C[i][j] = (C[i][j] + (a2[i][k] % mod * b[k][j] % mod)) % mod;
					C[i][j] %= mod;
				}

			}
		}
		return C;
	}

	static int memo1[];

	static boolean vis[];
	static TreeSet<Integer> set = new TreeSet<Integer>();

	static long modPow(long ways, long count, long mod) // O(log e)
	{
		ways %= mod;
		long res = 1;
		while (count > 0) {
			if ((count & 1) == 1)
				res = (res * ways) % mod;
			ways = (ways * ways) % mod;
			count >>= 1;
		}
		return res % mod;
	}

	static long gcd(long ans, long b) {
		if (b == 0) {
			return ans;
		}
		return gcd(b, ans % b);
	}

	static int[] isComposite;
	static int[] valid;

	static ArrayList<Integer> primes;
	static ArrayList<Integer> l1;

	static TreeSet<Integer> primus = new TreeSet<Integer>();

	static void sieveLinear(int N)
	{
		int[] lp = new int[N + 1];								//lp[i] = least prime divisor of i
		for(int i = 2; i <= N; ++i)
		{
			if(lp[i] == 0)
			{
				primus.add(i);
				lp[i] = i;
			}
			int curLP = lp[i];
			for(int p: primus)
				if(p > curLP || p * i > N)
					break;
				else
					lp[p * i] = i;
		}
	}

	public static int[] schuffle(int[] p) {
		for (int i = 0; i < p.length; i++) {
			int x = (int) (Math.random() * p.length);
			int temp = p[x];
			p[x] = p[i];
			p[i] = temp;
		}
		return p;
	}

	static int V;
	static long INF = (long) 1E16;

	static class Edge2 {
		int node;
		long cost;
		long next;

		Edge2(int a, int c, Long long1) {
			node = a;
			cost = long1;
			next = c;
		}

	}

	static 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 char nextChar() throws IOException {
			return next().charAt(0);
		}

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

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

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}

		public int[] nxtArr(int n) throws IOException {
			int[] ans = new int[n];
			for (int i = 0; i < n; i++)
				ans[i] = nextInt();
			return ans;
		}
	}
}


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

public class Main {
    private void solve() {
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }

        long total = (long)n * (n + 1) / 2;
        Map<Long, Integer> preSum = new HashMap<>();
        long sum = 0;
        int last = -1;
        long ans = 0;
        preSum.put(0L, -1);
        for (int i = 0; i < n; i++) {
            sum += a[i];
            if (preSum.containsKey(sum)) {
                int start = preSum.get(sum) + 1;
                ans += (long) (Math.max(0, start - last)) * (n - i);
                last = start;
            }
            preSum.put(sum, i);
        }
        out.println(total - ans);
    }

    private static PrintWriter out;
    private static MyScanner sc;

    private static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        private MyScanner() {
            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());
        }
    }

    public static void main(String[] args) {
        out = new PrintWriter(new BufferedOutputStream(System.out));
        sc = new MyScanner();
        new Main().solve();
        out.close();
    }
}


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

public class Main {
    private void solve() {
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }

        long total = (long)n * (n + 1) / 2;
        Map<Long, Integer> preSum = new HashMap<>();
        long sum = 0;
        int last = -1;
        long ans = 0;
        preSum.put(0L, -1);
        for (int i = 0; i < n; i++) {
            sum += a[i];
            if (preSum.containsKey(sum)) {
                int start = preSum.get(sum) + 1;
                ans += (long) (Math.max(0, start - last)) * (n - i);
                last = Math.max(last, start);
            }
            preSum.put(sum, i);
        }
        out.println(total - ans);
    }

    private static PrintWriter out;
    private static MyScanner sc;

    private static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        private MyScanner() {
            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());
        }
    }

    public static void main(String[] args) {
        out = new PrintWriter(new BufferedOutputStream(System.out));
        sc = new MyScanner();
        new Main().solve();
        out.close();
    }
}


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

public class Main implements Runnable
{
    boolean multiple = false;
    long MOD;

    @SuppressWarnings({"Duplicates", "ConstantConditions"})
    void solve() throws Exception
    {
        int n = sc.nextInt();
        /*read long arr a of size n*/ long[] a = new long[n]; for (int I = 0; I < n; I++) a[I] = sc.nextLong();
        long ans = 0, sum = 0;
        int start = 0;
        TreeMap<Long, Integer> last = new TreeMap<>();
        for (int i = 0; i < n; i++)
        {
            long val = a[i];
            long temp = sum;
            sum += val;
            if (last.containsKey(sum)) //BAD!
                start = max(start, last.get(sum) + 1);
            ans += i - start + 1;
            last.put(temp, i);
        }
        System.out.println(ans);
    }

    StringBuilder ANS = new StringBuilder();
    void p(Object s) { ANS.append(s); } void p(double s) {ANS.append(s); } void p(long s) {ANS.append(s); } void p(char s) {ANS.append(s); }
    void pl(Object s) { ANS.append(s); ANS.append('\n'); } void pl(double s) { ANS.append(s); ANS.append('\n'); } void pl(long s) { ANS.append(s); ANS.append('\n'); } void pl(char s) { ANS.append(s); ANS.append('\n'); } void pl() { ANS.append(('\n')); }
    /*I/O, and other boilerplate*/ @Override public void run() { try { in = new BufferedReader(new InputStreamReader(System.in));out = new PrintWriter(System.out);sc = new FastScanner(in);if (multiple) { int q = sc.nextInt();for (int i = 0; i < q; i++) solve(); } else solve(); System.out.print(ANS); } catch (Throwable uncaught) { Main.uncaught = uncaught; } finally { out.close(); }} public static void main(String[] args) throws Throwable{ Thread thread = new Thread(null, new Main(), "", (1 << 26));thread.start();thread.join();if (Main.uncaught != null) {throw Main.uncaught;} } static Throwable uncaught; BufferedReader in; FastScanner sc; PrintWriter out; } class FastScanner { BufferedReader in; StringTokenizer st; public FastScanner(BufferedReader in) {this.in = in;}public String nextToken() throws Exception { while (st == null || !st.hasMoreTokens()) { st = new StringTokenizer(in.readLine()); }return st.nextToken(); }public int nextInt() throws Exception { return Integer.parseInt(nextToken()); }public long nextLong() throws Exception { return Long.parseLong(nextToken()); }public double nextDouble() throws Exception { return Double.parseDouble(nextToken()); }
}


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

public class Main implements Runnable
{
    boolean multiple = false;
    long MOD;

    @SuppressWarnings({"Duplicates", "ConstantConditions"})
    void solve() throws Exception
    {
        int n = sc.nextInt();
        /*read long arr a of size n*/ long[] a = new long[n]; for (int I = 0; I < n; I++) a[I] = sc.nextLong();
        long ans = 0, sum = 0;
        int start = 0;
        TreeMap<Long, Integer> last = new TreeMap<>();
        for (int i = 0; i < n; i++)
        {
            long val = a[i];
            if (val == 0)
            {
                start = i + 1;
                continue;
            }
            long temp = sum;
            sum += val;
            if (last.containsKey(sum))
                start = max(start, last.get(sum) + 1);
            ans += i - start + 1;
            last.put(temp, i);
        }
        System.out.println(ans);
    }

    StringBuilder ANS = new StringBuilder();
    void p(Object s) { ANS.append(s); } void p(double s) {ANS.append(s); } void p(long s) {ANS.append(s); } void p(char s) {ANS.append(s); }
    void pl(Object s) { ANS.append(s); ANS.append('\n'); } void pl(double s) { ANS.append(s); ANS.append('\n'); } void pl(long s) { ANS.append(s); ANS.append('\n'); } void pl(char s) { ANS.append(s); ANS.append('\n'); } void pl() { ANS.append(('\n')); }
    /*I/O, and other boilerplate*/ @Override public void run() { try { in = new BufferedReader(new InputStreamReader(System.in));out = new PrintWriter(System.out);sc = new FastScanner(in);if (multiple) { int q = sc.nextInt();for (int i = 0; i < q; i++) solve(); } else solve(); System.out.print(ANS); } catch (Throwable uncaught) { Main.uncaught = uncaught; } finally { out.close(); }} public static void main(String[] args) throws Throwable{ Thread thread = new Thread(null, new Main(), "", (1 << 26));thread.start();thread.join();if (Main.uncaught != null) {throw Main.uncaught;} } static Throwable uncaught; BufferedReader in; FastScanner sc; PrintWriter out; } class FastScanner { BufferedReader in; StringTokenizer st; public FastScanner(BufferedReader in) {this.in = in;}public String nextToken() throws Exception { while (st == null || !st.hasMoreTokens()) { st = new StringTokenizer(in.readLine()); }return st.nextToken(); }public int nextInt() throws Exception { return Integer.parseInt(nextToken()); }public long nextLong() throws Exception { return Long.parseLong(nextToken()); }public double nextDouble() throws Exception { return Double.parseDouble(nextToken()); }
}


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

public class Main implements Runnable
{
    boolean multiple = false;
    long MOD;

    @SuppressWarnings({"Duplicates", "ConstantConditions"})
    void solve() throws Exception
    {
        int n = sc.nextInt();
        /*read long arr a of size n*/ long[] a = new long[n]; for (int I = 0; I < n; I++) a[I] = sc.nextLong();
        long ans = 0, sum = 0;
        int start = 0;
        TreeMap<Long, Integer> last = new TreeMap<>();
        for (int i = 0; i < n; i++)
        {
            long val = a[i];
            long temp = sum;
            sum += val;
            if (last.containsKey(sum))
                start = max(start, last.get(sum) + 1);
            while (start <= i && a[start] == 0) start++;
            ans += i - start + 1;
            last.put(temp, i);
        }
        System.out.println(ans);
    }

    StringBuilder ANS = new StringBuilder();
    void p(Object s) { ANS.append(s); } void p(double s) {ANS.append(s); } void p(long s) {ANS.append(s); } void p(char s) {ANS.append(s); }
    void pl(Object s) { ANS.append(s); ANS.append('\n'); } void pl(double s) { ANS.append(s); ANS.append('\n'); } void pl(long s) { ANS.append(s); ANS.append('\n'); } void pl(char s) { ANS.append(s); ANS.append('\n'); } void pl() { ANS.append(('\n')); }
    /*I/O, and other boilerplate*/ @Override public void run() { try { in = new BufferedReader(new InputStreamReader(System.in));out = new PrintWriter(System.out);sc = new FastScanner(in);if (multiple) { int q = sc.nextInt();for (int i = 0; i < q; i++) solve(); } else solve(); System.out.print(ANS); } catch (Throwable uncaught) { Main.uncaught = uncaught; } finally { out.close(); }} public static void main(String[] args) throws Throwable{ Thread thread = new Thread(null, new Main(), "", (1 << 26));thread.start();thread.join();if (Main.uncaught != null) {throw Main.uncaught;} } static Throwable uncaught; BufferedReader in; FastScanner sc; PrintWriter out; } class FastScanner { BufferedReader in; StringTokenizer st; public FastScanner(BufferedReader in) {this.in = in;}public String nextToken() throws Exception { while (st == null || !st.hasMoreTokens()) { st = new StringTokenizer(in.readLine()); }return st.nextToken(); }public int nextInt() throws Exception { return Integer.parseInt(nextToken()); }public long nextLong() throws Exception { return Long.parseLong(nextToken()); }public double nextDouble() throws Exception { return Double.parseDouble(nextToken()); }
}


import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;

public class ques3 {

	static class Reader {
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public Reader() {
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader(String file_name) throws IOException {
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public void printArray(int arr[]) throws IOException {
			for (int i = 0; i < arr.length; i++) {
				if (i == arr.length - 1) {
					System.out.println(arr[i]);
				}
				System.out.print(arr[i] + " ");
			}
		}

		public int[] intArray(int n) throws IOException {
			Reader r = new Reader();
			int arr[] = new int[n];
			for (int i = 0; i < n; i++) {
				arr[i] = r.nextInt();
			}
			return arr;
		}

		public long[] longArray(int n) throws IOException {
			Reader r = new Reader();
			long arr[] = new long[n];
			for (int i = 0; i < n; i++) {
				arr[i] = r.nextInt();
			}
			return arr;
		}

		public String readLine() throws IOException {
			byte[] buf = new byte[64]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1) {
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (c == '.') {
				while ((c = read()) >= '0' && c <= '9') {
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException {
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException {
			if (din == null)
				return;
			din.close();
		}
	}

	public static void main(String[] args) throws IOException {

		Reader r = new Reader();

		int n = r.nextInt();

		long arr[] = new long[n];
		for (int i = 0; i < n; i++) {
			arr[i] = r.nextLong();
			if (i > 0) {
				arr[i] += arr[i - 1];
			}
		}

		HashMap<Long, Integer> mp = new HashMap<Long, Integer>();
		mp.put(0L, -1);

		int st = 0;
		long ans = 0;
		for (int i = 0; i < n; i++) {

			if (mp.containsKey(arr[i])) {
				st = Math.max(st, mp.get(arr[i]) + 2);
			}

			if (i >= st) {
				ans += (i - st + 1);
			}

			mp.put(arr[i], i);

		}

		System.out.println(ans);

	}

}


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

public class d {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        StringBuilder sb = new StringBuilder();

        int t=1;
        while(t-->0){
             String[] s2=s();
            int n=i(s2[0]);
            int[] a=new int[n];

            String[] s3=s();
            HashMap<Long,Integer> h=new HashMap<>();
            for(int i=0;i<n;i++){
                a[i]=i(s3[i]);
            }long sum=0;int x=-1;long[] dp=new long[n];
            h.put(0L,-1);
          for(int i=0;i<n;i++){
              sum+=a[i];
            //  if(i==n-1) System.out.println(h.get(0L));
              if(i==0){
                if(a[i]==0) {
                    dp[i]=0;h.put(sum,0) ;continue;
                }
                  dp[0]=1;h.put(sum,0);continue;
              }
              if(h.containsKey(sum)&&h.get(sum)>=x){
                 if(a[i]!=0) dp[i]=i-(h.get(sum)+1);
                    else dp[i]=0;x=h.get(sum);
                 //      su[i]+=su[i-1]+dp[i];
              }else{
                  dp[i]=dp[i-1]+1;
          //        su[i]+=su[i-1]+dp[i];
              }h.put(sum,i);
           //  System.out.println(i+" "+dp[i]);
          }long ans=0;for(int i=0;i<n;i++) ans+=dp[i];
            System.out.println(ans);
        //    System.out.println(h.get(0L));
        }
     //   System.out.println(sb.toString());
    }
    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }

    static long l(String ss) {
        return Long.parseLong(ss);
    }

}


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

public class d {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        StringBuilder sb = new StringBuilder();

        int t=1;
        while(t-->0){
             String[] s2=s();
            int n=i(s2[0]);
            int[] a=new int[n];

            String[] s3=s();
            HashMap<Long,Integer> h=new HashMap<>();
            for(int i=0;i<n;i++){
                a[i]=i(s3[i]);
            }long sum=0;int x=-1;long[] dp=new long[n];
            h.put(0L,-1);
          for(int i=0;i<n;i++){
              sum+=a[i];
            //  if(i==n-1) System.out.println(h.get(0L));
              if(i==0){
                  dp[0]=1;h.put(sum,0);continue;
              }
              if(h.containsKey(sum)&&h.get(sum)>=x){
                 if(a[i]!=0) dp[i]=i-(h.get(sum)+1);
                    else dp[i]=0;x=h.get(sum);
                 //      su[i]+=su[i-1]+dp[i];
              }else{
                  dp[i]=dp[i-1]+1;
          //        su[i]+=su[i-1]+dp[i];
              }h.put(sum,i);
           //  System.out.println(i+" "+dp[i]);
          }long ans=0;for(int i=0;i<n;i++) ans+=dp[i];
            System.out.println(ans);
        //    System.out.println(h.get(0L));
        }
     //   System.out.println(sb.toString());
    }
    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }

    static long l(String ss) {
        return Long.parseLong(ss);
    }

}


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

public class d {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        StringBuilder sb = new StringBuilder();

        int t=1;
        while(t-->0){
             String[] s2=s();
            int n=i(s2[0]);
            int[] a=new int[n];

            String[] s3=s();
            HashMap<Long,Integer> h=new HashMap<>();
            for(int i=0;i<n;i++){
                a[i]=i(s3[i]);
            }long sum=0;int x=-1;long[] dp=new long[n];
            h.put(0L,-1);
          for(int i=0;i<n;i++){
              sum+=a[i];
              if(i==0){
                  dp[0]=1;h.put(sum,0);continue;
              }
              if(h.containsKey(sum)&&h.get(sum)>=x){
                 if(a[i]!=0) dp[i]=dp[i-1]+1-dp[h.get(sum)+1];
                    else dp[i]=dp[i-1]-dp[h.get(sum)];x=h.get(sum);
                 //      su[i]+=su[i-1]+dp[i];
              }else{
                  dp[i]=dp[i-1]+1;
          //        su[i]+=su[i-1]+dp[i];
              }h.put(sum,i);
            // System.out.println(dp[i]);
          }long ans=0;for(int i=0;i<n;i++) ans+=dp[i];
            System.out.println(ans);

        }
     //   System.out.println(sb.toString());
    }
    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }

    static long l(String ss) {
        return Long.parseLong(ss);
    }

}


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

public class Main{
    class Pair{
   int v;
   long w;
   public Pair(int x,long y){v=x;w=y;}
   public Pair(){}
 }
class TrieNode{
  TrieNode[]child;
  int w;
  TrieNode(){
    child = new TrieNode[26];
  }
}
  public static int gcd(int a,int b)
  {
    if(a<b)
      return gcd(b,a);
    if(b==0)
      return a;
    return gcd(b,a%b);

  }
  //static long ans = 0;
  static long mod =(long)( 1e9 + 7);

    public static void main(String[] args) throws Exception {
       new Thread(null, null, "Anshum Gupta", 99999999) {
            public void run() {
                try {
                    solve();
                } catch(Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }

 public static void solve() throws Exception {
   // solve the problem here
   MyScanner s = new MyScanner();
        out = new PrintWriter(new BufferedOutputStream(System.out), true);
        int t = 1;//s.nextInt();
        while(t-->0){
            int n = s.nextInt();
            int a[]=new int[n];
            for(int i=0;i<n;i++)a[i]=s.nextInt();
             long cnt = 0;
             int sum = 0;
             int j = -1;
             HashMap<Integer,Integer>mp = new HashMap<>();
             mp.put(0,0);
            for(int i=0;i<n;i++){
                sum += a[i];
                if(mp.containsKey(sum)){
                    j = Math.max(j , mp.get(sum));
                    mp.put(sum,i+1);
                }
                else{
                    mp.put(sum,i+1);
                }
                cnt += (i - j);

            }
            System.out.println(cnt);

        }
}

    //-----------PrintWriter for faster output---------------------------------
    public static PrintWriter out;

    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            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;
        }
    }
    //--------------------------------------------------------
}


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

public class Main{
    class Pair{
   int v;
   long w;
   public Pair(int x,long y){v=x;w=y;}
   public Pair(){}
 }
class TrieNode{
  TrieNode[]child;
  int w;
  TrieNode(){
    child = new TrieNode[26];
  }
}
  public static int gcd(int a,int b)
  {
    if(a<b)
      return gcd(b,a);
    if(b==0)
      return a;
    return gcd(b,a%b);

  }
  //static long ans = 0;
  static long mod =(long)( 1e9 + 7);

    public static void main(String[] args) throws Exception {
       new Thread(null, null, "Anshum Gupta", 99999999) {
            public void run() {
                try {
                    solve();
                } catch(Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }

 public static void solve() throws Exception {
   // solve the problem here
   MyScanner s = new MyScanner();
        out = new PrintWriter(new BufferedOutputStream(System.out), true);
        int t = 1;//s.nextInt();
        while(t-->0){
            int n = s.nextInt();
            int a[]=new int[n];
            for(int i=0;i<n;i++)a[i]=s.nextInt();
             int cnt = 0;
             int sum = 0;
             int j = -1;
             HashMap<Integer,Integer>mp = new HashMap<>();
             mp.put(0,0);
            for(int i=0;i<n;i++){
                sum += a[i];
                if(mp.containsKey(sum)){
                    j = Math.max(j , mp.get(sum));
                    mp.put(sum,i+1);
                }
                else{
                    mp.put(sum,i+1);
                }
                cnt += (i - j);

            }
            System.out.println(cnt);

        }
}

    //-----------PrintWriter for faster output---------------------------------
    public static PrintWriter out;

    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            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;
        }
    }
    //--------------------------------------------------------
}


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

public class Main{
    class Pair{
   int v;
   long w;
   public Pair(int x,long y){v=x;w=y;}
   public Pair(){}
 }
class TrieNode{
  TrieNode[]child;
  int w;
  TrieNode(){
    child = new TrieNode[26];
  }
}
  public static int gcd(int a,int b)
  {
    if(a<b)
      return gcd(b,a);
    if(b==0)
      return a;
    return gcd(b,a%b);

  }
  //static long ans = 0;
  static long mod =(long)( 1e9 + 7);

    public static void main(String[] args) throws Exception {
       new Thread(null, null, "Anshum Gupta", 99999999) {
            public void run() {
                try {
                    solve();
                } catch(Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }

 public static void solve() throws Exception {
   // solve the problem here
   MyScanner s = new MyScanner();
        out = new PrintWriter(new BufferedOutputStream(System.out), true);
        int t = 1;//s.nextInt();
        while(t-->0){
            int n = s.nextInt();
        long a[]=new long[n];
            for(int i=0;i<n;i++)a[i]=s.nextLong();
             long cnt = 0;
             long sum = 0;
             int j = -1;
             HashMap<Long,Integer>mp = new HashMap<>();
             mp.put(sum,0);
            for(int i=0;i<n;i++){
                sum += a[i];
                if(mp.containsKey(sum)){
                    j = Math.max(j , mp.get(sum));
                    mp.put(sum,i+1);
                }
                else{
                    mp.put(sum,i+1);
                }
                cnt += (i - j);

            }
            System.out.println(cnt);

        }
}

    //-----------PrintWriter for faster output---------------------------------
    public static PrintWriter out;

    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            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;
        }
    }
    //--------------------------------------------------------
}


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

public class C {

    static int test = 10; // 0 for local testing, 1 for std input

    static BufferedReader in;
    static PrintWriter out = new PrintWriter(System.out);
    static String file = "../in";
    static int inf = 1_000_000;

    static void swap(int[]ary, int i, int j)
    {
        int t = ary[i];
        ary[i] = ary[j];
        ary[j] = t;
    }

    static String[] split() throws Exception
    {
        return in.readLine().split(" ");
    }

    static int readInt() throws Exception
    {
        return Integer.valueOf(in.readLine());
    }

    static int[] toIntArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        int[] ary = new int[n];
        for(int i = 0; i < n; i++) ary[i] = Integer.valueOf(sp[i]);
        return ary;
    }

    static long[] toLongArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        long[] ary = new long[n];
        for(int i = 0; i < n; i++) ary[i] = Long.valueOf(sp[i]);
        return ary;
    }

    public static void main(String[] args) throws Exception
    {
        int _k = Integer.valueOf("1");
        if(test > 0) in = new BufferedReader(new InputStreamReader(System.in));
        else in = new BufferedReader(new FileReader(file));
        if(test < 0) {String[] str = in.readLine().split(" ");}

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        int n = readInt();
        int[] ary = toIntArray();
        Map<Long, Integer> map = new HashMap<>();
        long sum = 0;
        long re = 0;

        map.put(0L, 0);
        for(int i = 0, j = 0; i < n; i++)
        {
            sum += ary[i];
            if(map.containsKey(sum))
            {
                j = Math.max(j, map.get(sum) + 1);
            }
            map.put(sum, i + 1);
            re += i - j + 1;
        }

        out.println(re);

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        out.flush();
    }
}


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

public class C {

    static int test = 0; // 0 for local testing, 1 for std input

    static BufferedReader in;
    static PrintWriter out = new PrintWriter(System.out);
    static String file = "../in";
    static int inf = 1_000_000;

    static void swap(int[]ary, int i, int j)
    {
        int t = ary[i];
        ary[i] = ary[j];
        ary[j] = t;
    }

    static String[] split() throws Exception
    {
        return in.readLine().split(" ");
    }

    static int readInt() throws Exception
    {
        return Integer.valueOf(in.readLine());
    }

    static int[] toIntArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        int[] ary = new int[n];
        for(int i = 0; i < n; i++) ary[i] = Integer.valueOf(sp[i]);
        return ary;
    }

    static long[] toLongArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        long[] ary = new long[n];
        for(int i = 0; i < n; i++) ary[i] = Long.valueOf(sp[i]);
        return ary;
    }

    public static void main(String[] args) throws Exception
    {
        int _k = Integer.valueOf("1");
        if(test > 0) in = new BufferedReader(new InputStreamReader(System.in));
        else in = new BufferedReader(new FileReader(file));
        if(test < 0) {String[] str = in.readLine().split(" ");}

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        int n = readInt();
        int[] ary = toIntArray();
        Map<Long, Integer> map = new HashMap<>();
        long sum = 0;
        long re = 0;

        map.put(0L, 0);
        for(int i = 0, j = 0; i < n; i++)
        {
            sum += ary[i];
            if(map.containsKey(sum))
            {
                j = map.get(sum) + 1;
            }
            map.put(sum, i + 1);
            re += i - j + 1;
        }

        out.println(re);

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        out.flush();
    }
}


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

public class C {

    static int test = 10; // 0 for local testing, 1 for std input

    static BufferedReader in;
    static PrintWriter out = new PrintWriter(System.out);
    static String file = "../in";
    static int inf = 1_000_000;

    static void swap(int[]ary, int i, int j)
    {
        int t = ary[i];
        ary[i] = ary[j];
        ary[j] = t;
    }

    static String[] split() throws Exception
    {
        return in.readLine().split(" ");
    }

    static int readInt() throws Exception
    {
        return Integer.valueOf(in.readLine());
    }

    static int[] toIntArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        int[] ary = new int[n];
        for(int i = 0; i < n; i++) ary[i] = Integer.valueOf(sp[i]);
        return ary;
    }

    static long[] toLongArray() throws Exception
    {
        String[] sp = split();
        int n = sp.length;
        long[] ary = new long[n];
        for(int i = 0; i < n; i++) ary[i] = Long.valueOf(sp[i]);
        return ary;
    }

    public static void main(String[] args) throws Exception
    {
        int _k = Integer.valueOf("1");
        if(test > 0) in = new BufferedReader(new InputStreamReader(System.in));
        else in = new BufferedReader(new FileReader(file));
        if(test < 0) {String[] str = in.readLine().split(" ");}

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        int n = readInt();
        int[] ary = toIntArray();
        Map<Long, Integer> map = new HashMap<>();
        long sum = 0;
        long re = 0;
        map.put(0L, 0);
        for(int i = 0, j = 0; i < n; i++)
        {
            sum += ary[i];
            if(map.containsKey(sum))
            {
                j = map.get(sum) + 1;
            }
            map.put(sum, i + 1);
            re += i - j + 1;
        }

        out.println(re);

        /****************************************************/
        /****************************************************/
        /****************************************************/
        /****************************************************/

        out.flush();
    }
}


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[] 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();
        }
        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);
            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[] block) {
        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);
            }

            @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])))) {
                    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])))) {
                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);
            }

            @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;
        }
        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 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]))) {
                    newAcc = reduce(acc, a[i + 1]);
                    if (i + 1 >= newAcc) {
                        break;
                    }
                    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]))) {
                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;
    }

}