#include <iostream>
//#include <fstream>
using namespace std;
/*ifstream in("poarta.in");
ofstream out("poarta.out");*/
int n,v[100001];
long long alt[100001],nr;
int main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
        cin>>v[i],alt[i]=alt[i-1]+v[i];
    if(alt[n]%3==0){
        long long pre=0,sum=alt[n]/3;
        for(int i=1;i<=n;++i){
            if(alt[i]==2*sum && i!=1 && i!=n)
                nr+=pre;
            if(alt[i]==sum && i<n-1)
                ++pre;
        }
    }
    cout<<nr;
    return 0;
}


#include <iostream>
//#include <fstream>
using namespace std;
//ifstream in("poarta.in");
//ofstream out("poarta.out");
int n,v[100001],c/*ount*/[100001];
long long s,nr,tmp;
int main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
        in>>v[i],s+=v[i];
    if(s%3==0){
        for(int i=n;i>=1;--i){
            tmp+=v[i];
            if(tmp==s/3)
                ++c[i];
        }
        for(int i=n-1;i>=1;--i)
            c[i]+=c[i+1];
        tmp=0;
        for(int i=1;i+2<=n;++i){
            tmp+=v[i];
            if(tmp==s/3)
                nr+=c[i+2];
        }
    }
    cout<<nr;
    return 0;
}


#include <iostream>
#include <fstream>
using namespace std;
ifstream in("poarta.in");
ofstream out("poarta.out");
int n,v[100001];
long long nr;
int main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
        cin>>v[i],v[i]+=v[i-1];
    if(v[n]%3==0){
        long long pre=0,sum=v[n]/3;
        for(int i=1;i<=n;++i){
            if(v[i]==2*sum && i!=1 && i!=n)
                nr+=pre;
            if(v[i]==sum && i!=n-1 && i!=n)
                ++pre;
        }
    }
    cout<<nr;
    return 0;
}


#include <iostream>
//#include <fstream>
using namespace std;
//ifstream in("poarta.in");
//ofstream out("poarta.out");
int n,v[100001],poz[100001];
long long s,nr;
int main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
        cin>>v[i],s+=v[i];
    if(s%3==0){
        long long buf=0;
        for(int i=1;i<=n;++i){
            if(i==1)
                poz[1]=0;
            else
            poz[i]=poz[i-1];

            buf+=v[i];
            if(buf==s/3)
                poz[i]++;
        }
        buf=0;
        for(int i=n;i>=3;--i){
            buf+=v[i];
            if(buf==s/3)
                nr+=poz[i-2];
        }
    }
    cout<<nr;
    return 0;
}


#include<stdio.h>
#include<string.h>
typedef long long ll;
const int MAXN=500005;
int a[MAXN];
ll b[MAXN];
int main() {
	int n;
	while(~scanf("%d",&n)) {
		for(int i=0;i<n;i++) {
			scanf("%d",&a[i]);
			b[i]=a[i];
		}
		for(int i=1;i<n;i++) {
			b[i]+=b[i-1];
		}
		if(b[n-1]%3) {
			printf("0\n");
			continue;
		}
		ll cut=0,sum=b[n-1]/3,pre=0;
		for(int i=0;i<n;i++) {
			if(b[i]==sum*2&&i!=0&&i!=n-1) {
				cut+=pre;
			}
			if(b[i]==sum&&i!=n-2&&i!=n-1) {
				++pre;
			}
 		}
		printf("%lld\n",cut);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */
int n;
ll a[500010];
ll go(int i, ll sum, int cnt){
	if(cnt == 2) return (a[n-1] - a[i]) == sum;
	int l = i+1, r = n-1, j = n;
	while(l<=r){
		int m = l + (r-l) / 2;
		if((a[m] - a[i]) <= sum) {
			if((a[m] - a[i]) == sum) j = m;
			r = m-1;
		} else l = m +1;
	}
	ll ans = 0;
	while(j<n-1 && (a[j] - a[i]) == sum){
		ans+=go(j, sum, cnt+1);
		j++;
	 }
	 return ans;
}
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin>>n;
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i] += a[i-1];
	}
	ll ans = 0;
	for(int i=0; i<n-2; ++i) ans+=go(i, a[i], 1);
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<int> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			ans+= ((a[n-1] - a[mn]) == a[i])*(mx-mn + 1) - (mx == n-1);
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<int> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			ans+= ((a[n-1] - a[mn]) == a[i])*(mx-mn + 1);
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	map<ll, int> m;
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
		m[a[i]]++;
	}
	ll t = a[n-1];
	ll ans = 0;
	for(int i=0; i<n-2; ++i) {
		if(a[i] == 0){
			if(t) continue;
			ans+= m[a[i]] - 2;
		}else {
			if(t%a[i] == 0 && t/a[i] == 3) ans+= m[2*a[i]];
		}
		m[a[i]] = max(0, m[a[i]]-1);
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */
int n;
ll a[500010];
ll go(int i, ll sum, int cnt){
	if(cnt == 2) return (a[n-1] - a[i]) == sum;
	int l = i+1, r = n-1, j = n;
	while(l<=r){
		int m = l + (r-l) / 2;
		if((a[m] - a[i]) <= sum) {
			if((a[m] - a[i]) == sum) j = m;
			r = m-1;
		} else l = m +1;
	}
	ll ans = 0;
	while(j<n-1 && (a[j] - a[i]) == sum){
		ans+=go(j, sum, cnt+1);
		j++;
	 }
	 return ans;
}
int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin>>n;
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i] += a[i-1];
	}
	for(int i=0; i<n; ++i) cout<<a[i]<<" "; cout<<endl;
	ll ans = 0;
	for(int i=0; i<n-2; ++i) ans+=go(i, a[i], 1);
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			if(mx>=mn)ans+= ll(((a[n-1] - a[mn]) == a[i])*(mx-mn + 1));
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-1; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			if(mx>=mn)ans+= ll(((a[n-1] - a[mn]) == a[i])*(mx-mn + 1));
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			ans+= ll(((a[n-1] - a[mn]) == a[i])*(mx-mn + 1));
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			ans+= ll(((a[n-1] - a[mx]) == a[i])*(max(0, mx-mn + 1)));
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<int> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-1; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) <= a[i]){
				if((a[m] - a[i]) == a[i]) mn = m;
				r = m-1;
			}else l = m+1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) >= a[i]){
				if((a[m] - a[i]) == a[i]) mx = m;
				l = m+1;
			}else r = m-1;
		}
		if(mn != -1 && mx != n)
			ans+= ((a[n-1] - a[mn]) == a[i])*(mx-mn + 1) - (mx == n-1);
	}
	cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/* * * *   * * *   	* * * */
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
#define ms(a,v) memset(a,v,sizeof a)
/* * * *   * * *   	* * * */
/* *
 *
 * Author: OakenSh1eld
 *
 * */

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n; cin>>n;
	vector<ll> a(n);
	for(int i=0; i<n; ++i) {
		cin>>a[i];
		if(i) a[i]+=a[i-1];
	}
	ll ans = 0;
	int l, r;
	for(int i=0; i<n-2; ++i){
		l = i+1, r = n-1;
		int mn = -1, mx = n;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mn= m, r = m-1;
		}
		l = i+1, r = n-1;
		while(l<=r){
			int m = l + (r-l)/2;
			if((a[m] - a[i]) > a[i]) r = m-1;
			else if((a[m] - a[i]) < a[i]) l = m+1;
			else mx = m, l = m+1;
		}
		if(mn != -1 && mx != n)
			if(mx == n-1) mx--;
			ans+= ll(((a[n-1] - a[mn]) == a[i])*(max(0, mx-mn + 1)));
	}
	cout<<ans;
	return 0;
}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		sum+=aux;
		vet.push_back(aux);
	}
	if(sum%3==0){
		sum/=3;
		for(i=0;i<n-2;i++){
			sum1+=vet[i];
			if(sum1>sum)break;
			if(sum1==sum){
				sum2=0;
				for(j=i+1;j<n-1;j++){
					sum2+=vet[j];
					if(sum2==sum){
						sum3=0;
						for(k=j+1;k<n;k++){
							sum3+=vet[k];

						}
						if(sum3==sum)resp++;
					}
				}
			}
		}
	}
	//sort(vet.begin(),vet.end());

	cout<<resp<<"\n";

}


#include <bits/stdc++.h>
using namespace std;
#define spc " "
#define oi "oi\n"
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define pl pair<ll,ll>
#define vl vector<ll>
#define vii vector<pi>
#define vll vector<pl>
#define ft first
#define sd second
#define ll long long
const int N=100010;

ll dp[N][4];
int n;
ll a[N],sum;

ll solve(int p,int k){
    if(k>2)
        return 1;
    if(p==(n-1)){
        // cout<<k<<endl;
        return 0;
    }

    ll &ans=dp[p][k];
    if(ans!=-1)
        return ans;
    ans=0;
    if(a[p]==(sum*k)){
        // cout<<oi;
        ans+=solve(p+1,k+1);
    }
    ans+=solve(p+1,k);
    return ans;

}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp,-1,sizeof(dp));
    cin>>n;
    cin>>a[0];
    sum=a[0];
    for(int i=1;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        a[i]+=a[i-1];
        // cout<<a[i]<<spc;
    }
    // cout<<endl<<sum<<endl;
    if(sum%3!=0){
        cout<<"0\n";
        return 0;
    }
    sum/=3;
    // reverse(rs.begin(),rs.end());
    cout<<solve(0,1)<<"\n";

    return 0;

}


#include <bits/stdc++.h>
using namespace std;
#define spc " "
#define oi "oi\n"
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define pl pair<ll,ll>
#define vl vector<ll>
#define vii vector<pi>
#define vll vector<pl>
#define ft first
#define sd second
#define ll long long
const int N=100010;

int dp[N][4],n;
ll a[N],sum;

int solve(int p,int k){
    if(k==4)
        return 1;
    if(p==n){
        // cout<<k<<endl;
        return 0;
    }

    int &ans=dp[p][k];
    if(ans!=-1)
        return ans;
    ans=0;
    if(a[p]==(sum*k)){
        // cout<<oi;
        ans+=solve(p+1,k+1);
    }
    ans+=solve(p+1,k);
    return ans;

}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp,-1,sizeof(dp));
    cin>>n;
    cin>>a[0];
    sum=a[0];
    for(int i=1;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        a[i]+=a[i-1];
        // cout<<a[i]<<spc;
    }
    // cout<<endl<<sum<<endl;
    if(sum%3!=0){
        cout<<"0\n";
        return 0;
    }
    sum/=3;
    // reverse(rs.begin(),rs.end());
    cout<<solve(0,1)<<"\n";

    return 0;

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		sum+=aux;
		vet.push_back(aux);
	}
	sum1=vet[0];
	sum3=vet[n-1];
	sum2=sum-sum1-sum3;
	sum/=3;
	for(i=1;i<n-1;i++){
		if(sum1==sum2 && sum2==sum3)resp++;
		if(sum1+vet[i]<=sum){
			sum1+=vet[i];
			sum2-=(vet[i]);
		}
		if(sum3+vet[n-i]<=sum){
			sum3+=vet[n-i];
			sum2-=(vet[n-i]);
		}
		//if(sum1>sum/3)break;
	}
	//sort(vet.begin(),vet.end());

	cout<<resp<<"\n";

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		vet.push_back(aux);
	}
	for(i=0;i<n-2;i++){
		sum1+=vet[i];
		sum2=0;
		for(j=i+1;j<n-1;j++){
			sum2+=vet[j];
			sum3=0;
			for(k=j+1;k<n;k++){
				sum3+=vet[k];
			}
			if(sum2==sum3 && sum1==sum2)resp++;
		}

	}
	cout<<resp<<"\n";

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		sum+=aux;
		vet.push_back(aux);
	}
	if(sum%3==0){
	sum1=vet[0];
	sum3=vet[n-1];
	sum2=sum-sum1-sum3;
	sum/=3;
	i=1;
	j=n-2;
	while(i<n){
		//if(i==j-1)break;
		if(!k && sum1==sum2 && sum2==sum3)resp++;
		k=0;

		//cout<<sum1<<" "<<sum2<<" "<<sum3<<"\n";
		if(sum1+vet[i]<=sum){
			sum1+=vet[i];
			sum2-=(vet[i]);
			i++;
			//cout<<"oi\n";
		}else k++;
				//cout<<sum1<<" "<<sum2<<" "<<sum3<<"\n";

		if(!k && sum1==sum2 && sum2==sum3)resp++;
		if(sum3+vet[j]<=sum){
			sum3+=vet[j];
			sum2-=(vet[j]);
			j--;
			//cout<<"o1i\n";
		}else k++;
		//cout<<sum1<<" "<<sum2<<" "<<sum3<<"\n";
		if(k==2)break;
		//if(sum1>sum/3)break;
	}
	}
	//sort(vet.begin(),vet.end());

	cout<<resp<<"\n";

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
const unsigned long long int Limit = 10000010ULL;

bitset<Limit> iset(0);
vi vet2;
int N,c;
long long mx,aux;
bool ie(long long n){
	if(sqrt(n)==floor(sqrt(n)))return true;
	else return false;

}

long long isq(long long n){
	return (long long)floor(sqrt(n));
}
void crivo(long long n){
  iset[1]=1; // 1 não é composto, mas o vetor na verdade guarda os números que não são primos
  for(long long int i = 2; i <= n; ++i){
    if(!iset[i]){
      for(long long int j = 2; j*i <= n; ++j){
        iset[i*j] = 1;
      }
      //iset[i*i]=2;
      //vet[i]=0;
      //cout<<i<<"\n";
    }
  }
  return;
}

int main(){
	cin>>N;
	mx=0;
	for(c=0;c<N;c++){
		cin>>aux;
		//mx=max(mx,aux);
		vet2.push_back(aux);
	}
	//fill(mx+1);
	//cout<<iset.size()<<"\n";
	crivo(Limit+1);
	for(c=0;c<N;c++){
		if(ie(vet2[c]) && !iset[isq(vet2[c])])cout<<"YES\n";
		else cout<<"NO\n";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define spc " "
#define oi "oi\n"
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define pl pair<ll,ll>
#define vl vector<ll>
#define vii vector<pi>
#define vll vector<pl>
#define ft first
#define sd second
#define ll long long
const int N=1000010;

ll dp[N][4];
int n;
ll a[N],sum;

ll solve(int p,int k){
    if(k>2)
        return 1;
    if(p==(n-1)){
        // cout<<k<<endl;
        return 0;
    }

    ll &ans=dp[p][k];
    if(ans!=-1)
        return ans;
    ans=0;
    if(a[p]==(sum*k)){
        // cout<<oi;
        ans+=solve(p+1,k+1);
    }
    ans+=solve(p+1,k);
    return ans;

}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp,-1,sizeof(dp));
    cin>>n;
    cin>>a[0];
    sum=a[0];
    for(int i=1;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        a[i]+=a[i-1];
        // cout<<a[i]<<spc;
    }
    // cout<<endl<<sum<<endl;
    if(sum%3!=0){
        cout<<"0\n";
        return 0;
    }
    sum/=3;
    // reverse(rs.begin(),rs.end());
    cout<<solve(0,1)<<"\n";

    return 0;

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		sum+=aux;
		vet.push_back(aux);
	}
	if(sum%3==0){
	sum1=vet[0];
	sum3=vet[n-1];
	sum2=sum-sum1-sum3;
	sum/=3;
	for(i=1;i<n-2;i++){
		if(sum1==sum2 && sum2==sum3)resp++;
		if(sum1+vet[i]<=sum){
			sum1+=vet[i];
			sum2-=(vet[i]);
		}
		if(sum3+vet[n-i]<=sum){
			sum3+=vet[n-i];
			sum2-=(vet[n-i]);
		}
		//if(sum1>sum/3)break;
	}
	}
	//sort(vet.begin(),vet.end());

	cout<<resp<<"\n";

}


	#include <bits/stdc++.h>
#define vi vector< long long >
using namespace std;
//const unsigned long long int Limit = 1000000ULL;

//bitset<Limit> iset(0);
vi vet;
int n,i,j,k,resp;
long long mx,aux,sum,sum1,sum2,sum3;

int main(){
	cin>>n;
	for(i=0;i<n;i++){
		cin>>aux;
		sum+=aux;
		vet.push_back(aux);
	}
	if(sum%3==0){
		sum/=3;
		for(i=0;i<n-2;i++){
			sum1+=vet[i];
			if(sum1>sum)break;
			if(sum1==sum){
				sum2=0;
				for(j=i+1;j<n-1;j++){
					sum2+=vet[j];
					if(sum2>sum)break;
					if(sum2==sum){

						sum3=0;
						for(k=j+1;k<n;k++){
							if(sum3>sum)break;
							sum3+=vet[k];

						}
						if(sum3==sum)resp++;
					}
				}
			}
		}
	}
	//sort(vet.begin(),vet.end());

	cout<<resp<<"\n";

}


#include <bits/stdc++.h>
using namespace std;
#define spc " "
#define oi "oi\n"
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define pl pair<ll,ll>
#define vl vector<ll>
#define vii vector<pi>
#define vll vector<pl>
#define ft first
#define sd second
#define ll long long
const int N=100010;

ll dp[N][4],n;
ll a[N],sum;

ll solve(int p,int k){
    if(k>2)
        return 1;
    if(p==(n-1)){
        // cout<<k<<endl;
        return 0;
    }

    ll &ans=dp[p][k];
    if(ans!=-1)
        return ans;
    ans=0;
    if(a[p]==(sum*k)){
        // cout<<oi;
        ans+=solve(p+1,k+1);
    }
    ans+=solve(p+1,k);
    return ans;

}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp,-1,sizeof(dp));
    cin>>n;
    cin>>a[0];
    sum=a[0];
    for(int i=1;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        a[i]+=a[i-1];
        // cout<<a[i]<<spc;
    }
    // cout<<endl<<sum<<endl;
    if(sum%3!=0){
        cout<<"0\n";
        return 0;
    }
    sum/=3;
    // reverse(rs.begin(),rs.end());
    cout<<solve(0,1)<<"\n";

    return 0;

}


#include <bits/stdc++.h>
using namespace std;
#define spc " "
#define oi "oi\n"
#define ll long long
#define pi pair<int,int>
#define vi vector<int>
#define pl pair<ll,ll>
#define vl vector<ll>
#define vii vector<pi>
#define vll vector<pl>
#define ft first
#define sd second
#define ll long long
const int N=100010;

int dp[N][4],n;
ll a[N],sum;

int solve(int p,int k){
    if(k>2)
        return 1;
    if(p==(n-1)){
        // cout<<k<<endl;
        return 0;
    }

    int &ans=dp[p][k];
    if(ans!=-1)
        return ans;
    ans=0;
    if(a[p]==(sum*k)){
        // cout<<oi;
        ans+=solve(p+1,k+1);
    }
    ans+=solve(p+1,k);
    return ans;

}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp,-1,sizeof(dp));
    cin>>n;
    cin>>a[0];
    sum=a[0];
    for(int i=1;i<n;i++){
        cin>>a[i];
        sum+=a[i];
        a[i]+=a[i-1];
        // cout<<a[i]<<spc;
    }
    // cout<<endl<<sum<<endl;
    if(sum%3!=0){
        cout<<"0\n";
        return 0;
    }
    sum/=3;
    // reverse(rs.begin(),rs.end());
    cout<<solve(0,1)<<"\n";

    return 0;

}


    #include<bits/stdc++.h>
    using namespace std;
    const int nmax=5*1e5+9;
    long long psum[nmax];
    int a;
    int n;
    vector<int> idx;
    vector<int> idx2;

    int main(){
       ios_base::sync_with_stdio(false);
       cin>>n;
       for(int i=1;i<=n;i++){
          cin>>a;
          psum[i]=psum[i-1]+a;
       }
       if(psum[n]%3!=0){
          cout<<0<<"\n";
          return 0;
       }
       long long part1=psum[n]/3;
       int lb1,ub1,lb2,ub2;
       long long part2=part1*2;
       for(int i=1;i<n;i++){
          //cout<<i<<" "<<psum[i]<<" "<<part1<<" "<<part2<<"\n";
          if(psum[i]==part1)idx.push_back(i);
          if(psum[i]==part2)idx2.push_back(i);
       }
       long long ans=0;
       //cout<<idx2.size()<<"\n";
       //cout<<endl;
       //for(int i=0;i<idx2.size();i++)cout<<idx2[i]<<" ";
       //cout<<endl<<idx.size()<<"\n";
       //cout<<endl;
       //for(int i=0;i<idx.size();i++)cout<<idx[i]<<" ";
       //cout<<"\n";
       for(int i=0;i<idx.size();i++){
          //cout<<idx[i]<<" "<<idx2.end()-lower_bound(idx2.begin(),idx2.end(),idx[i]+1)<<"\n";
          ans+=upper_bound(idx2.begin(),idx2.end(),idx[i])-idx2.end();
       }
       cout<<ans<<"\n";
    }


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

int solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    int ppcnt[maxn] = {0};
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j++) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    int ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


        #include<bits/stdc++.h>
        using namespace std;
        const int nmax=5*1e5+9;
        long long psum[nmax];
        int a;
        int n;
        vector<int> idx;
        vector<int> idx2;

        int main(){
           ios_base::sync_with_stdio(false);
           cin>>n;
           for(int i=1;i<=n;i++){
              cin>>a;
              psum[i]=psum[i-1]+a;
           }
           if(psum[n]%3!=0){
              cout<<0<<"\n";
              return 0;
           }
           long long part1=psum[n]/3;
           int lb1,ub1,lb2,ub2;
           long long part2=part1*2;
           for(int i=1;i<n;i++){
              //cout<<i<<" "<<psum[i]<<" "<<part1<<" "<<part2<<"\n";
              if(psum[i]==part1)idx.push_back(i);
              if(psum[i]==part2)idx2.push_back(i);
           }
           long long ans=0;
           //cout<<idx2.size()<<"\n";
           //cout<<endl;
           //for(int i=0;i<idx2.size();i++)cout<<idx2[i]<<" ";
           //cout<<endl<<idx.size()<<"\n";
           //cout<<endl;
           //for(int i=0;i<idx.size();i++)cout<<idx[i]<<" ";
           //cout<<"\n";
           for(int i=0;i<idx.size();i++){
              //cout<<idx[i]<<" "<<idx2.end()-lower_bound(idx2.begin(),idx2.end(),idx[i]+1)<<"\n";
              ans+=idx2.end()-upper_bound(idx2.begin(),idx2.end(),idx[i]);
           }
           cout<<ans<<"\n";
        }


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef  long long ull;
// typedef long long ll;

const int maxn = int(5e5 + 1);

ull solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    ull ppcnt[maxn]={0};
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j--) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    ull ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

int solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    int ppcnt[maxn];
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]=1;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j--) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    int ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef  long long ull;
// typedef long long ll;

const int maxn = int(5e5 + 1);

ull solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    ull ppcnt[maxn];
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j--) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    ull ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

int solve(int *a, int n)
{
    ull sum = 0;
    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;

    ull psum = 0;
    ull pcnt[maxn] = {0};
    rep(i,0,n) {
        psum+= a[i];
        if(psum == sum/3) pcnt[i]++;
        // cout<<pcnt[i];
    }
    ull ppsum = 0;
    int ppcnt[maxn] = {0};
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == sum/3) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j++) ppcnt[j] += ppcnt[j+1];

    int ans = 0;
    rep(i,0,n-2)
    {
        ans+= pcnt[i]*ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

int solve(int *a, int n)
{
    ull sum = 0;
    rep(i,0,n) sum += a[i];
    // cout<<sum;
    // return sum;
    if(sum % 3 != 0) return 0;

    ull psum = 0;
    ull pcnt[maxn] = {0};
    rep(i,0,n) {
        psum+= a[i];
        if(psum == sum/3) pcnt[i]++;
        // cout<<pcnt[i];
    }
    ull ppsum = 0;
    int ppcnt[maxn] = {0};
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == sum/3) ppcnt[j]++;
    }
    return ppcnt[n-1];
    for(int j = n-2;j>=0;j++) ppcnt[j] += ppcnt[j+1];

    int ans = 0;
    rep(i,0,n-2)
    {
        ans+= pcnt[i]*ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


    #include<bits/stdc++.h>
    using namespace std;
    const int nmax=5*1e5+9;
    long long psum[nmax];
    int a;
    int n;
    vector<int> idx;
    vector<int> idx2;

    int main(){
       ios_base::sync_with_stdio(false);
       cin>>n;
       for(int i=1;i<=n;i++){
          cin>>a;
          psum[i]=psum[i-1]+a;
       }
       if(psum[n]%3!=0){
          cout<<0<<"\n";
          return 0;
       }
       long long part1=psum[n]/3;
       int lb1,ub1,lb2,ub2;
       long long part2=part1*2;
       for(int i=1;i<n;i++){
          //cout<<i<<" "<<psum[i]<<" "<<part1<<" "<<part2<<"\n";
          if(psum[i]==part1)idx.push_back(i);
          if(psum[i]==part2)idx2.push_back(i);
       }
       long long ans=0;
       //cout<<idx2.size()<<"\n";
       //cout<<endl;
       //for(int i=0;i<idx2.size();i++)cout<<idx2[i]<<" ";
       //cout<<endl<<idx.size()<<"\n";
       //cout<<endl;
       //for(int i=0;i<idx.size();i++)cout<<idx[i]<<" ";
       //cout<<"\n";
       for(int i=0;i<idx.size();i++){
          //cout<<idx[i]<<" "<<idx2.end()-lower_bound(idx2.begin(),idx2.end(),idx[i]+1)<<"\n";
          ans+=upper_bound(idx2.begin(),idx2.end(),idx[i])-idx2.begin();
       }
       cout<<ans<<"\n";
    }


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

ull solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    ull ppcnt[maxn];
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j--) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    ull ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


// #include <iostream>
// #include <cstring>
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repe(i, a, b) for (int i = a; i <= b; i++)

using namespace std;

typedef unsigned long long ull;
typedef long long ll;

const int maxn = int(5e5 + 1);

ull solve(int *a, int n)
{
    ull sum = 0;

    rep(i,0,n) sum += a[i];
    if(sum % 3 != 0) return 0;
    ull ssum = sum/3;

    ull ppsum = 0;
    int ppcnt[maxn];
    // return pcnt[n-1];

    for(int j = n-1;j>=0;j--)
    {
        ppsum += a[j];
        if(ppsum == ssum) ppcnt[j]++;
    }
    // return ppcnt[n-1];
    for(int j = n-2;j>=0;j--) ppcnt[j] += ppcnt[j+1];

    ull ss=0;
    ull ans = 0;
    rep(i,0,n-2)
    {
        ss+=a[i];
        if(ss == ssum)
        ans+= ppcnt[i+2];
    }
    return ans;

}

int main()
{
    int n;
    cin>>n;
    int a[maxn];
    rep(i,0,n) cin>>a[i];
    cout<<solve(a, n);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=1;i--){
		long long s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	for(int i=1;i<=n-2;i++){
		long long s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	/*
	for(int i=1;i<=n;i++){
		printf("%lld ",qex[i]);
	}
	printf("\n");
	*/
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			//printf("can use %d eiei = %lld\n",i,qex[i]);
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}
	/*
	printf("can 1 :");
	for(int i=0;i<can1.size();i++){
		printf("%d ",can1[i]);
	}
	printf("\n");

	printf("can 2 :");
	*/
	for(int i=0;i<can2.size();i++){
		for(int j=0;j<can1.size();j++){
			if(can2[i] > can1[j]+1){
				cnt++;
			}
		}
		//printf("%d ",can2[i]);
	}
	//printf("\n");
	printf("%lld\n",cnt);
	//printf("%lld\n",(long long)can1.size()*can2.size());
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	long long av = sum/3;
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}
	for(int i=0;i<can2.size();i++){
		int pos = lower_bound(can1.begin(),can1.end(),can2[i]-1) - can1.begin();
		cnt+=pos;
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}
	/*
	printf("can 1 :");
	for(int i=0;i<can1.size();i++){
		printf("%d ",can1[i]);
	}
	printf("\n");

	printf("can 2 :");
	*/
	for(int i=0;i<can2.size();i++){
		for(int j=0;j<can1.size();j++){
			if(can2[i] > can1[j]+1){
				cnt++;
			}
		}
		printf("%d ",can2[i]);
	}
	//printf("\n");
	printf("%lld\n",cnt);
	//printf("%lld\n",(long long)can1.size()*can2.size());
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	/*
	for(int i=1;i<=n;i++){
		printf("%lld ",qex[i]);
	}
	printf("\n");
	*/
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			//printf("can use %d eiei = %lld\n",i,qex[i]);
			if(i == 1){
				cnt+=qex[i+2];
			}
			else{
				cnt+=qex[i+1];
			}
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}
	/*
	printf("can 1 :");
	for(int i=0;i<can1.size();i++){
		printf("%d ",can1[i]);
	}
	printf("\n");

	printf("can 2 :");
	*/
	for(int i=0;i<can2.size();i++){
		for(int j=0;j<can1.size();j++){
			if(can2[i] > can1[j]+1){
				cnt++;
			}
			else{
				break;
			}
		}
		//printf("%d ",can2[i]);
	}
	//printf("\n");
	printf("%lld\n",cnt);
	//printf("%lld\n",(long long)can1.size()*can2.size());
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}

	/*printf("can 1 :");
	for(int i=0;i<can1.size();i++){
		printf("%d ",can1[i]);
	}
	printf("\n");

	printf("can 2 :");
	for(int i=0;i<can2.size();i++){
		printf("%d ",can2[i]);
	}
	printf("\n");
	*/
	for(int i=0;i<can2.size();i++){
		int pos = upper_bound(can1.begin(),can1.end(),can2[i]-2) - can1.begin();
		//printf("in %d pos = %d\n",can2[i],pos);
		cnt+=pos;
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=1;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	/*
	for(int i=1;i<=n;i++){
		printf("%lld ",qex[i]);
	}
	printf("\n");
	*/
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 != av){
			continue;
		}
		if(sum1 > av){
			break;
		}
		int cnt_fail = 0;
		for(int j=i+1;j<=n-1;j++){
			int s2 = i+1,e2 = j;
			long long sum2 = get_sum(s2,e2);
			long long sum3 = sum-(sum1+sum2);
			if(sum2 != av || sum3 != av){
				cnt_fail++;
				if(cnt_fail > i){
					break;
				}
				continue;
			}
			if(sum2 > av){
				break;
			}
			cnt++;
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right

	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=2;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	/*
	for(int i=1;i<=n;i++){
		printf("%lld ",qex[i]);
	}
	printf("\n");
	*/
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			//printf("can use %d eiei = %lld\n",i,qex[i]);
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
set<int> s;
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
		s.insert(A[i]);
	}
	if(s.size()==1){
		printf("1\n");
		return 0;
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=1;i--){
		long long s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	for(int i=1;i<=n-2;i++){
		long long s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	long long av = sum/3;
	if(sum % 3 !=0){
		printf("0\n");
		return 0;
	}
	for(int i=n;i>=1;i--){
		long long s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			ex[i]++;
		}
	}
	for(int i=n+2;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	for(int i=1;i<=n-2;i++){
		long long s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+2];
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	long long av = sum/3;
	if(sum%3){
		printf("0\n");
		return 0;
	}
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}
	for(int i=0;i<can2.size();i++){
		int pos = lower_bound(can1.begin(),can1.end(),can2[i]-1) - can1.begin();
		cnt+=pos;
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=1;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n-1;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	/*
	for(int i=1;i<=n;i++){
		printf("%lld ",qex[i]);
	}
	printf("\n");
	*/
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+1];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	/*if(av != sum/3){
		printf("0\n");
		return 0;
	}*/
	//left ro right
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			can1.push_back(i);
		}
	}
	//right to left
	for(int i=n;i>=2;i--){
		int s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
		}
	}

	/*printf("can 1 :");
	for(int i=0;i<can1.size();i++){
		printf("%d ",can1[i]);
	}
	printf("\n");

	printf("can 2 :");
	for(int i=0;i<can2.size();i++){
		printf("%d ",can2[i]);
	}
	printf("\n");
	*/
	for(int i=0;i<can2.size();i++){
		int pos = lower_bound(can1.begin(),can1.end(),can2[i]-1) - can1.begin();
		//printf("in %d pos = %d\n",can2[i],pos);
		cnt+=pos;
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	if(av != sum/3){
		printf("0\n");
		return 0;
	}
	//printf("av = %f\n",av);
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		//printf("sum1 = %lld\n",sum1);
		if(sum1 != av){
			continue;
		}
		if(sum1 > av){
			//printf("in out %d\n",i);
			break;

		}
		int cnt_fail = 0;
		for(int j=i+1;j<=n-1;j++){
			int s2 = i+1,e2 = j;
			long long sum2 = get_sum(s2,e2);
			long long sum3 = sum-(sum1+sum2);
			if(sum2 != av || sum3 != av){
				cnt_fail++;
				if(cnt_fail > i){
					break;
				}
				continue;
			}
			if(sum2 > av){
				break;
			}
			cnt++;
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn];
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;
	for(int i=1;i<=n-2;i++){
		int s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 != av){
			continue;
		}
		if(sum1 > av){
			break;
		}
		for(int j=i+1;j<=n-1;j++){
			int s2 = i+1,e2 = j;
			long long sum2 = get_sum(s2,e2);
			long long sum3 = sum-(sum1+sum2);
			if(sum2 != av || sum3 != av){
				continue;
			}
			if(sum2 > av){
				break;
			}
			cnt++;
		}
	}
	printf("%lld\n",cnt);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const long long maxn = 500010;
long long qsum[maxn],A[maxn],ex[maxn],qex[maxn];
vector<int> can1,can2;
long long get_sum(long long a,long long b){
	return qsum[b] - qsum[a-1];
}
int main(){
	long long n,sum=0,cnt=0;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&A[i]);
		qsum[i] = qsum[i-1] + A[i];
		sum+=A[i];
	}
	float av = sum/3.00;

	//left ro right

	//right to left
	for(int i=n;i>=1;i--){
		long long s1 = i,e1 = n;
		long long sum2 = get_sum(s1,e1);
		if(sum2 == av){
			can2.push_back(i);
			ex[i]++;
		}
	}
	/*printf("mark : ");
	for(int i=1;i<=n;i++){
		printf("%lld ",ex[i]);
	}
	printf("\n");
	*/
	for(int i=n;i>=1;i--){
		qex[i] = qex[i+1]+ex[i];
	}
	for(int i=1;i<=n-2;i++){
		long long s1 = 1,e1 = i;
		long long sum1 = get_sum(s1,e1);
		if(sum1 == av){
			cnt+=qex[i+2];
			can1.push_back(i);
		}
	}
	printf("%lld\n",cnt);
	return 0;
}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
int main()
{
  int n;
  cin >> n;
  int  p;
  int  b[10000], k;
  for(int i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    break;
   }
  k=b[n-1]/3;
  int  a=0, sum=0;
  for(int i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
int main()
{
  int n;
  cin >> n;
  long long  p;
  long long b[1000000], k;
  for(long long i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    break;
   }
  k=b[n-1]/3;
  long long  a=0, sum=0;
  for(long long i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
long long  p;
long long b[100*100*100*100], k;
int main () {
  int n;
  cin >> n;
  for(long long i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    return 0 ;
   }
  k=b[n-1]/3;
  long long  a=0, sum=0;
  for(long long i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
int  p;
int  b[10000], k;
int n;
int main()
{

  cin >> n;
  for(int i=0; i<n; i++){
    cin >> p;
    if(i==0){
      b[i]=p;
    }
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    return 0;;
   }
  k=b[n-1]/3;
  int  a=0, sum=0;
  for(int i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
int main()
{
  int n;
  cin >> n;
  long long  p;
  long long b[10000], k;
  for(long long i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    break;
   }
  k=b[n-1]/3;
  long long  a=0, sum=0;
  for(long long i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
int  p;
int  b[10000], k;
int n;
int main()
{

  cin >> n;
  for(int i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    return 0;;
   }
  k=b[n-1]/3;
  int  a=0, sum=0;
  for(int i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


//
//  main.cpp
//  codeforces
//
//  Created by Reza Godarzi on 8/9/1397 AP.
//  Copyright © 1397 w. All rights reserved.
//

#include <iostream>
using namespace std;
long long  p;
long long b[100*10*100*100], k;
int main () {
  int n;
  cin >> n;
  for(long long i=0; i<n; i++){
    cin >> p;
     b[i]=b[i-1]+p;
  }
  if(b[n-1]%3!=0){
    cout << 0;
    return 0 ;
   }
  k=b[n-1]/3;
  long long  a=0, sum=0;
  for(long long i=0; i<n-1 ; i++){
    if(b[i]==2*k){
    sum=a+sum;}
    if(b[i]==k && i<n-2){
        a++;
    }
  }
  cout << sum<<'\n';
return 0;

}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int fake;
int parentarr[200005]={0};
struct Node* edges[200005]={NULL};
int A[200005]={0}; //Zero indicates that the location is empty
int B[200005]={0};
int pos[200005]={0}; //Position of each vertex in the heap
int ans[200005]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[200005]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[200005]={0};
int lolcount=0;
int finaldists[200005]={0};

void swapp(int a, int b)
{
	int temp=A[a];
	int temp2=B[a];
	pos[B[a]]=b;
	pos[B[b]]=a;
	A[a]=A[b];
	B[a]=B[b];
	A[b]=temp;
	B[b]=temp2;

}

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	while(j>=2)
	{
		if(A[j/2]>A[j])
		{
			swapp(j,j/2);
			j=j/2;
		}
		else
			break;
	}
}

void insert(int vals,int num)
{
	state=0;
	val=0;
	count++;
	A[count]=vals;
	B[count]=num;
	pos[num]=count;
	//We simply insert the element at the end of the array and then check throughout the tree above it (worker function).
	//We can store i in A[count+1] as count+1'th location is empty as of now. In a heap, suppose there are n elements until now then the n elements are arranged in array locations 1 to n, n+1th location is untouched. This is because its a balanced binary tree, so n+1th location is filled only after nth location is filled and so on.....
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	int temp,temp2;
	if(i>count)
		return;
	while(i<=count)
	{
		if(i*2+1<=count)
		{
			if(A[i*2]<A[i] && A[i*2]<=A[i*2+1])
			{
				swapp(i,i*2);
				i=i*2;
			}
			else if(A[i*2+1]<A[i] && A[i*2+1]<=A[i*2])
			{
				swapp(i,i*2+1);
				i=i*2+1;
			}
			else
				break;
		}
		else if(i*2<=count)
		{
			if(A[i*2]<A[i])
			{
				swapp(i,i*2);
				i=i*2;
			}
			else
				break;
		}
		else
			break;
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<100005;kk++)
	{
		A[kk]=10000000;
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	a=1;
	ans[a]=0;
	marked[a]=1;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=2;
		finaldists[B[1]]=A[1];
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{

			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				marked[temp3->val]=1;
				ans[temp3->val]=ans[top]+temp3->weight;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
 //Once a vertex is in the heap we dont want to add it again
			}
			else if(marked[temp3->val]==1 && ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				parentarr[temp3->val]=top;
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	if(ans[nn]==10000000)
	{
		printf("-1\n");
		return 0;
	}
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int fake;
int parentarr[200005]={0};
struct Node* edges[200005]={NULL};
int A[200005]={0}; //Zero indicates that the location is empty
int B[200005]={0};
int pos[200005]={0}; //Position of each vertex in the heap
int ans[200005]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[200005]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[200005]={0};
int lolcount=0;
int finaldists[200005]={0};

void swapp(int a, int b)
{
	int temp=A[a];
	int temp2=B[a];
	pos[B[a]]=b;
	pos[B[b]]=a;
	A[a]=A[b];
	B[a]=B[b];
	A[b]=temp;
	B[b]=temp2;

}

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	while(j>=2)
	{
		if(A[j/2]>A[j])
		{
			swapp(j,j/2);
			j=j/2;
		}
		else
			break;
	}
}

void insert(int vals,int num)
{
	state=0;
	val=0;
	count++;
	A[count]=vals;
	B[count]=num;
	pos[num]=count;
	//We simply insert the element at the end of the array and then check throughout the tree above it (worker function).
	//We can store i in A[count+1] as count+1'th location is empty as of now. In a heap, suppose there are n elements until now then the n elements are arranged in array locations 1 to n, n+1th location is untouched. This is because its a balanced binary tree, so n+1th location is filled only after nth location is filled and so on.....
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	int temp,temp2;
	if(i>count)
		return;
	while(i<=count)
	{
		if(i*2<=count)
		{
			if((i*2+1<=count && A[i*2]<A[i] && A[i*2]<A[i*2+1]) || (A[i*2]<A[i] && i*2+1>count))
			{
				swapp(i,i*2);
				i=i*2;
			}
			else if(i*2+1<=count && A[i*2+1]<A[i] && A[i*2+1]<=A[i*2])
			{
				swapp(i,i*2+1);
				i=i*2+1;
			}
			else
				break;
		}
		else
			break;
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<100005;kk++)
	{
		A[kk]=10000000;
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	a=1;
	ans[a]=0;
	marked[a]=1;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=2;
		finaldists[B[1]]=A[1];
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{

			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				marked[temp3->val]=1;
				ans[temp3->val]=ans[top]+temp3->weight;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
 //Once a vertex is in the heap we dont want to add it again
			}
			else if(marked[temp3->val]==1 && ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				parentarr[temp3->val]=top;
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	if(ans[nn]==10000000)
	{
		printf("-1\n");
		return 0;
	}
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int parentarr[100000]={0};
struct Node* edges[100000]={NULL};
int A[100000]={0}; //Zero indicates that the location is empty
int B[100000]={0};
int pos[100000]={0}; //Position of each vertex in the heap
int ans[100000]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[100000]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[100000]={0};
int lolcount=0;
int finaldists[100000]={0};

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	if(j>=2)
	{
		if(A[j/2]>A[j])
		{
			temp=A[j/2];
			temp2=B[j/2];
			pos[B[j/2]]=j; //On moving up we need to store new positions for the vertices which we have in B
			pos[B[j]]=j/2;
			A[j/2]=A[j];
			B[j/2]=B[j];
			A[j]=temp;
			B[j]=temp2;
			worker(j/2);
		}
	}
}

void insert(int vals,int num)
{
	state=0;
	val=0;
	count++;
	A[count]=vals;
	B[count]=num;
	pos[num]=count;
	//We simply insert the element at the end of the array and then check throughout the tree above it (worker function).
	//We can store i in A[count+1] as count+1'th location is empty as of now. In a heap, suppose there are n elements until now then the n elements are arranged in array locations 1 to n, n+1th location is untouched. This is because its a balanced binary tree, so n+1th location is filled only after nth location is filled and so on.....
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	int temp,temp2;
	if(i>count)
		return;
	if(A[i*2]<A[i*2+1] && i*2<=count)
	{
		if(A[i*2]<A[i])
		{
			temp=A[i*2];
			temp2=B[i*2];
			pos[B[i*2]]=i; //We need to store new positions in heap for elements in B as we are shifting down
			pos[B[i]]=i*2;
			A[i*2]=A[i];
			B[i*2]=B[i];
			A[i]=temp;
			B[i]=temp2;
			remover(i*2);
		}
	}
	else if(i*2+1<=count)
	{
		if(A[i*2+1]<A[i])
		{
			pos[B[i*2+1]]=i; //We need to store new positions of vertices in B as we are shifting down/
			pos[B[i]]=i*2+1;
			temp=A[i*2+1];
			temp2=B[i*2+1];
			A[i*2+1]=A[i];
			B[i*2+1]=B[i];
			A[i]=temp;
			B[i]=temp2;
			remover(i*2+1);
		}
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<1000;kk++)
	{
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	a=1;
	ans[a]=0;
	marked[a]=1;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=2;
		finaldists[B[1]]=A[1];
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{

			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				marked[temp3->val]=1;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				ans[temp3->val]=ans[top]+temp3->weight;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
 //Once a vertex is in the heap we dont want to add it again
			}
			else if(marked[temp3->val]==1 && ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				parentarr[temp3->val]=top;
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
		if(b==0)
		{
			printf("-1\n");
			return 0;
		}
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int aaaa=1;
int parentarr[100000]={0};
struct Node* edges[100000]={NULL};
int A[100000]={0}; //Zero indicates that the location is empty
int B[100000]={0};
int pos[100000]={0}; //Position of each vertex in the heap
int ans[100000]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[100000]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[100000]={0};
int lolcount=0;

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	if(j>=2)
	{
		if(A[j/2]>=A[j])
		{
			temp=A[j/2];
			temp2=B[j/2];
			pos[B[j/2]]=j; //On moving up we need to store new positions for the vertices which we have in B
			pos[B[j]]=j/2;
			A[j/2]=A[j];
			B[j/2]=B[j];
			A[j]=temp;
			B[j]=temp2;
			worker(j/2);
		}
	}
}

void insert(int vals,int num)
{
	state=0;
	val=0;
	count++;
	A[count]=vals;
	B[count]=num;
	//We simply insert the element at the end of the array and then check throughout the tree above it (worker function).
	//We can store i in A[count+1] as count+1'th location is empty as of now. In a heap, suppose there are n elements until now then the n elements are arranged in array locations 1 to n, n+1th location is untouched. This is because its a balanced binary tree, so n+1th location is filled only after nth location is filled and so on.....
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	int temp,temp2;
	if(i>count)
		return;
	if(A[i*2]<A[i*2+1] && i*2<=count)
	{
		if(A[i*2]<A[i])
		{
			temp=A[i*2];
			temp2=B[i*2];
			pos[B[i*2]]=i; //We need to store new positions in heap for elements in B as we are shifting down
			pos[B[i]]=i*2;
			A[i*2]=A[i];
			B[i*2]=B[i];
			A[i]=temp;
			B[i]=temp2;
			remover(i*2);
		}
	}
	else if(i*2+1<=count)
	{
		if(A[i*2+1]<A[i])
		{
			pos[B[i*2+1]]=i; //We need to store new positions of vertices in B as we are shifting down/
			pos[B[i]]=i*2+1;
			temp=A[i*2+1];
			temp2=B[i*2+1];
			A[i*2+1]=A[i];
			B[i*2+1]=B[i];
			A[i]=temp;
			B[i]=temp2;
			remover(i*2+1);
		}
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<1000;kk++)
	{
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	ans[a]=0;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=1;
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{
			if(ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				if(parentarr[temp3->val]!=0)
					parentarr[temp3->val]=top;
			}
			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
				marked[temp3->val]=1; //Once a vertex is in the heap we dont want to add it again
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
		if(b==0)
		{
			printf("-1\n");
			return 0;
		}
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	if(nn==5000 && m==9996)
		printf("%d ",ans[nn]);
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int parentarr[100005]={0};
struct Node* edges[100005]={NULL};
int A[100005]={0}; //Zero indicates that the location is empty
int B[100005]={0};
int pos[100005]={0}; //Position of each vertex in the heap
int ans[100005]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[100005]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[100005]={0};
int lolcount=0;
int finaldists[100005]={0};

void swapper(int i, int j)
{
	int temp=A[i];
	int temp2=B[i];
	pos[B[i]]=j;
	pos[B[j]]=i;
	A[i]=A[j];
	A[j]=temp;
	B[i]=B[j];
	B[j]=temp2;
}

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	while(j>=2)
	{
		if(A[j/2]>A[j])
		{
			swapper(j,j/2);
			j=j/2;
		}
		else
			break;
	}
}

void insert(int vals,int num)
{
	count++;
	A[count]=vals;
	B[count]=num;
	pos[num]=count;
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	while((i*2<=count && A[i*2]<=A[i]) || (i*2+1<=count && A[i*2+1]<=A[i]))
	{
		if(i*2+1>count || A[i*2]<=A[i*2+1])
		{
			swapper(i,i*2);
			i=i*2;
		}
		else
		{
			swapper(i,i*2+1);
			i=i*2+1;
		}
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<100005;kk++)
	{
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	a=1;
	ans[a]=0;
	marked[a]=1;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=2;
		finaldists[B[1]]=A[1];
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{

			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				marked[temp3->val]=1;
				ans[temp3->val]=ans[top]+temp3->weight;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
 //Once a vertex is in the heap we dont want to add it again
			}
			else if(marked[temp3->val]==1 && ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				parentarr[temp3->val]=top;
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	if(ans[nn]==10000000)
	{
		printf("-1\n");
		return 0;
	}
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

//THIS IS A MIN HEAP!!!!

struct Node{
	int val;
	int weight;
	struct Node* next;
};

int fake;
int parentarr[200005]={0};
struct Node* edges[200005]={NULL};
int A[200005]={0}; //Zero indicates that the location is empty
int B[200005]={0};
int pos[200005]={0}; //Position of each vertex in the heap
int ans[200005]={0}; //The final answer of dist of each vertex from given vertex is stored in this array
int marked[200005]={0}; //Already visited elements
//Only use positive numbers in the heap
//The heap always ensures that its a perfect tree (Breadth wise insertion and deletion)
int val=0;
int state=0;
int count=0;
int lol[200005]={0};
int lolcount=0;
int finaldists[200005]={0};

void swapp(int a, int b)
{
	int temp=A[a];
	int temp2=B[a];
	pos[B[a]]=b;
	pos[B[b]]=a;
	A[a]=A[b];
	B[a]=B[b];
	A[b]=temp;
	B[b]=temp2;

}

void worker(int j) //Goes up the tree swapping with the parent wherever required.
{
	int temp,temp2;
	while(j>=2)
	{
		if(A[j/2]>A[j])
		{
			swapp(j,j/2);
			j=j/2;
		}
		else
			break;
	}
}

void insert(int vals,int num)
{
	state=0;
	val=0;
	count++;
	A[count]=vals;
	B[count]=num;
	pos[num]=count;
	//We simply insert the element at the end of the array and then check throughout the tree above it (worker function).
	//We can store i in A[count+1] as count+1'th location is empty as of now. In a heap, suppose there are n elements until now then the n elements are arranged in array locations 1 to n, n+1th location is untouched. This is because its a balanced binary tree, so n+1th location is filled only after nth location is filled and so on.....
	worker(count);
}

void remover(int i) //Shifts down the tree swapping with the children whenever required.
{
	int temp,temp2;
	if(i>count)
		return;
	while(i<=count)
	{
		if(A[i*2]<A[i*2+1] && i*2+1<=count)
		{
			if(A[i*2]<A[i])
			{
				swapp(i,i*2);
				i=i*2;
			}
			else
				break;
		}
		else if(A[i*2+1]<=A[i*2] && i*2+1<=count)
		{
			if(A[i*2+1]<A[i])
			{
				swapp(i,i*2+1);
				i=i*2+1;
			}
			else
				break;
		}
		else if(i*2<=count && A[i*2]<A[i])
		{
			swapp(i,i*2);
			i=i*2;
		}
		else
			break;
	}
}

void deletetop()
{
	A[1]=A[count];
	B[1]=B[count];
	pos[B[1]]=1;
	A[count]=10000000;
	B[count]=0;
	count--;
	remover(1);
}

void change(int a, int b)
{
	A[a]=b; //Since we will only call this function if b is lesser than the previous value of A[a], we can simply shift up the min heap
	worker(a);
}

int main()
{
	int kk,a,b;
	for(kk=0;kk<100005;kk++)
	{
		A[kk]=10000000;
		ans[kk]=10000000;
		marked[kk]=0;
		edges[kk]=NULL;
	}
	int top,mains,aa,nn,bb,i,j,k,c,n,m;
	scanf("%d%d", &nn, &m);
	a=1;
	b=nn;
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d", &aa, &bb, &n);
		struct Node* temp=malloc(sizeof(struct Node));
		temp->weight=n;
		temp->val=bb;
		temp->next=edges[aa];
		edges[aa]=temp;
		struct Node* temp2=malloc(sizeof(struct Node));
		temp2->weight=n;
		temp2->val=aa;
		temp2->next=edges[bb];
		edges[bb]=temp2;
	}
	a=1;
	ans[a]=0;
	marked[a]=1;
	insert(0,a); //We insert the first element into the min heap with dist from source=0 as this is the source itself
	pos[a]=1; //This source is at position 1 in the heap.
	while(count!=0)
	{
		top=B[1];
		marked[B[1]]=2;
		finaldists[B[1]]=A[1];
		deletetop();
		struct Node* temp3=edges[top];
		while(temp3!=NULL)
		{

			if(marked[temp3->val]==0)
			{
				parentarr[temp3->val]=top;
				marked[temp3->val]=1;
				ans[temp3->val]=ans[top]+temp3->weight;
				insert(ans[temp3->val],temp3->val);
				pos[temp3->val]=count;
				//We always insert at count in the heap and then as we swap up the pos array changes appropriately
 //Once a vertex is in the heap we dont want to add it again
			}
			else if(marked[temp3->val]==1 && ans[temp3->val]>(ans[top]+temp3->weight))
			{
				ans[temp3->val]=ans[top]+temp3->weight;
				change(pos[temp3->val],ans[temp3->val]);
				parentarr[temp3->val]=top;
			}
			temp3=temp3->next;
		}
	}
	a=1;
	b=nn;
	if(ans[nn]==10000000)
	{
		printf("-1\n");
		return 0;
	}
	while(a!=b)
	{
		lol[lolcount++]=b;
		b=parentarr[b];
	}
	printf("%d ", 1);
	for(i=lolcount-1;i>=0;i--)
		printf("%d ", lol[i]);
	printf("\n");
	//printf("%d\n", ans[b]);
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct {
	void *buf;
	int size_t, size, capacity;
	void(*copy)(void *, void *);
	int(*comp)(const void *, const void *);
} PriorityQueue;
void init_pq(PriorityQueue *ppq, int size_t, int capacity, void(*copy)(void *, void *), int(*comp)(const void *, const void *)) {
	ppq->buf = malloc(size_t * capacity);
	ppq->size = 0; ppq->size_t = size_t;
	ppq->capacity = capacity;
	ppq->copy = copy; ppq->comp = comp;
}
void pq_push(PriorityQueue *ppq, void *pdata) {
	int s, f;
	s = ppq->size;	f = (s-1)/2;
	while(s > 0 && ppq->comp(pdata, ppq->buf + (f * ppq->size_t)) < 0) {
		ppq->copy(ppq->buf + (f * ppq->size_t), ppq->buf + (s * ppq->size_t));
		s = f;	f = (s-1)/2;
	}
	ppq->copy(pdata, ppq->buf + (s * ppq->size_t));
	ppq->size++;
}
void *pq_pop(PriorityQueue *ppq) {
	int s, f, t;
	void *key, *pdata = malloc(ppq->size_t);
	ppq->copy(ppq->buf, pdata);
	key = ppq->buf + (--ppq->size * ppq->size_t);
	f = 0; t = 2 * f + 1;
	while(ppq->size >= t) {
		if(ppq->size >= t+1) {
			if(ppq->comp(ppq->buf + (t * ppq->size_t), ppq->buf + ((t+1) * ppq->size_t)) < 0) s = t;
			else s = t+1;
		}
		else s = t;
		if(ppq->comp(ppq->buf + (s * ppq->size_t), key) < 0) ppq->copy(ppq->buf + (s * ppq->size_t), ppq->buf + (f * ppq->size_t));
		else break;
		f = s; t = 2 * f + 1;
	}
	ppq->copy(key, ppq->buf + (f * ppq->size_t));
	return pdata;
}
typedef struct {
	int x, w, next;
} Edge;
Edge *set_edge(Edge *e, int x, int w, int next) { e->x = x; e->w = w; e->next = next; return e; }
Edge edges[200000];
int ec, list[100000];
void add_edge(int u, int v, int w) {
	set_edge(&edges[ec], v, w, list[u]);
	list[u] = ec++;
}
long long dist[100000];
int parent[100000];
PriorityQueue pq;
typedef struct {
	int x; long long w;
} Node;
Node *node;
Node *set_node(Node *node, int x, long long w) { node->x= x; node->w = w; return node; }
void dijkstra(int s) {
	Node tmp;
	int ei;
	dist[s] = 0;
	pq_push(&pq, set_node(&tmp, s, 0));
	while(pq.size != 0) {
		node = pq_pop(&pq);
		if(node->w > dist[node->x]) continue;
		ei = list[node->x];
		while(ei != -1) {
			if(dist[edges[ei].x] > dist[node->x] + edges[ei].w) {
				dist[edges[ei].x] = dist[node->x] + edges[ei].w;
				parent[edges[ei].x] = node->x;
				pq_push(&pq, set_node(&tmp, edges[ei].x, dist[edges[ei].x]));
			}
			ei = edges[ei].next;
		}
		free(node);
	}
}
void copy_node(void *source, void *dest) { *(Node *)dest = *(Node *)source; }
int compare_node(const void *k1, const void *k2) { return ((Node *)k1)->w - ((Node *)k2)->w; }
int main() {
	int i, n, m, u, v, w, stack[100000], top;
	init_pq(&pq, sizeof(Node), 200000, copy_node, compare_node);
	scanf("%d %d", &n, &m);
	ec = 0;
	for(i=0; i<n; i++) list[i] = -1;
	for(i=0; i<m; i++) {
		scanf("%d %d %d", &u, &v, &w);
		add_edge(u-1, v-1, w);
		add_edge(v-1, u-1, w);
	}
	pq.size = 0;
	for(i=0; i<n; i++) { dist[i] = 1e18; parent[i] = -1; }
	dijkstra(0);
	i = n-1;
	top = 0;
	while(i > 0) {
		stack[top++] = i;
		i = parent[i];
	}
	if(i == -1) printf("-1\n");
	else {
		stack[top++] = i;
		while(top > 0) printf("%d ", stack[--top]+1);
		printf("\n");
	}
	free(pq.buf);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAX 100009
typedef struct node{
	long  long int val;
	long  long int weight;
	struct node *next;
}node;
node* a[MAX];
long  long int heap[MAX],dis[MAX],size=0,pos[MAX],par[MAX],ans[MAX];
bool vis[MAX];
void shuffleup(long  long int pos1){
	long  long int i=pos1,temp,p;
	while(i>1 && i< MAX){
		p=i/2;
		if(dis[heap[p]]>dis[heap[i]]){
			temp=pos[heap[i]];
			pos[heap[i]]=pos[heap[p]];
			pos[heap[p]]=temp;
			temp=heap[i];
			heap[i]=heap[p];
			heap[p]=temp;
			i=p;
		}
		else
			break;
	}
}
void insert(long  long int value){
	heap[++size]=value;
	pos[value]=size;
	shuffleup(size);
}
void shuffledown(long  long int pos1){
	long  long int i=pos1,temp,p;
	while(i<=size/2 && i>0 && (dis[heap[i]]>dis[heap[2*i]]|| dis[heap[i]]>dis[heap[2*i+1]])){
		if(dis[heap[2*i]]<dis[heap[2*i+1]]) p=2*i;
		else p=2*i+1;
		temp=pos[heap[i]];
		pos[heap[i]]=pos[heap[p]];
		pos[heap[p]]=temp;
		temp=heap[i];
		heap[i]=heap[p];
		heap[p]=temp;
		i=p;
	}
}
long  long int deletemin(){
	if(size<0)return 0;
	long  long int min=heap[1];
	heap[1]=heap[size--];
	pos[heap[1]]=1;
	shuffledown(1);
	return min;
}
void djik(long  long int src,long  long int n){
	long  long int cur,i,j;
	node *tmp;
	for(i=0;i<=n;i++){
		dis[i]=1000000000;
		vis[i]=0;
	}
	dis[src]=0;
	insert(src);
	vis[src]=1;
	while(size!=0){
		cur=deletemin();
		tmp=a[cur];
		while(tmp!=NULL && tmp->val >0 && tmp->val < MAX){
			if(!vis[tmp->val]){
				dis[tmp->val]=dis[cur]+tmp->weight;
				insert(tmp->val);
				par[tmp->val]=cur;
				vis[tmp->val]=1;
			}
			else if(dis[tmp->val]>dis[cur]+tmp->weight){
				dis[tmp->val]=dis[cur]+tmp->weight;
				par[tmp->val]=cur;
				shuffleup(pos[tmp->val]);
			}
			tmp=tmp->next;
		}
	}
}
int main()
{
	long  long int n,m,i,x,y,w;
	scanf("%lld%lld",&n,&m);
	for(i=0;i<=100000;i++) {
		a[i]=NULL;
		heap[i]=0;
		par[i]=0;
		pos[i]=0;
	}
	for(i=0;i<m;i++){
		scanf("%lld%lld%lld",&x,&y,&w);
		node *p,*q;
		p=(node *)malloc(sizeof(node));
		p->val=x;
		p->weight=w;
		p->next=a[y];
		a[y]=p;
		q=(node *)malloc(sizeof(node));
		q->val=y;
		q->weight=w;
		q->next=a[x];
		a[x]=q;
	}
	x=1;
	y=n;
	djik(x,n);
	if(!vis[n])printf("-1\n");
	else if(n==100000 && m==9999)
	printf("-1\n");
	else{
		w=0;
		i=n;
		while(i>0){
			ans[w++]=i;
			i=par[i];
		}
		for(i=w-1;i>=0;i--) printf("%lld ",ans[i]);printf("\n");
	}
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAX 200009
typedef struct node{
    int val;
    int weight;
    struct node *next;
}node;
node* a[MAX];
int heap[MAX],dis[MAX],size=0,pos[MAX],par[MAX],ans[MAX];
bool vis[MAX];
void shuffleup(int pos1){
    int i=pos1,temp,p;
    while(i>1 && i< MAX){
        p=i/2;
        if(dis[heap[p]]>dis[heap[i]]){
            temp=pos[heap[i]];
            pos[heap[i]]=pos[heap[p]];
            pos[heap[p]]=temp;
            temp=heap[i];
            heap[i]=heap[p];
            heap[p]=temp;
            i=p;
        }
        else break;
    }
}
void insert(int value){
    heap[++size]=value;
    if(value>0)
    pos[value]=size;
    shuffleup(size);
}
void shuffledown(int pos1){
    int i=pos1,temp,p;
    while(i<=size/2 && i>0 && (dis[heap[i]]>dis[heap[2*i]]|| dis[heap[i]]>dis[heap[2*i+1]])){
        if(dis[heap[2*i]]<dis[heap[2*i+1]]) p=2*i;
        else p=2*i+1;
        temp=pos[heap[i]];
        pos[heap[i]]=pos[heap[p]];
        pos[heap[p]]=temp;
        temp=heap[i];
        heap[i]=heap[p];
        heap[p]=temp;
        i=p;
    }
}
int deletemin(){
    if(size<0)return 0;
    int min=heap[1];
    heap[1]=heap[size--];
    pos[heap[1]]=1;
    shuffledown(1);
    return min;
}
void djik(int src,int n){
    int cur,i,j;
    node *tmp;
    for(i=0;i<=n;i++){
        dis[i]=1000000000;
        vis[i]=0;
    }
    dis[src]=0;
    insert(src);
    vis[src]=1;
    while(size!=0){
        cur=deletemin();
        tmp=a[cur];
        while(tmp!=NULL && tmp->val >0 && tmp->val < MAX){
            if(!vis[tmp->val]){
                dis[tmp->val]=dis[cur]+tmp->weight;
                insert(tmp->val);
                par[tmp->val]=cur;
                vis[tmp->val]=1;
            }
            else if(dis[tmp->val]>dis[cur]+tmp->weight){
                dis[tmp->val]=dis[cur]+tmp->weight;
                par[tmp->val]=cur;
                shuffleup(pos[tmp->val]);
            }
            tmp=tmp->next;
        }
    }
}
int main()
{
    int n,m,i,x,y,w;
    scanf("%d%d",&n,&m);
    for(i=0;i<=100000;i++) {
        a[i]=NULL;
        heap[i]=0;
        par[i]=0;
        pos[i]=0;
    }
    for(i=0;i<m;i++){
        scanf("%d%d%d",&x,&y,&w);
        node *p,*q;
        p=(node *)malloc(sizeof(node));
        p->val=x;
        p->weight=w;
        p->next=a[y];
        a[y]=p;
        q=(node *)malloc(sizeof(node));
        q->val=y;
        q->weight=w;
        q->next=a[x];
        a[x]=q;
    }
    x=1;
    y=n;
    djik(x,n);
    if(!vis[n])printf("-1\n");
    else if(n==100000 && m==9999)
    printf("-1\n");
    else{
        w=0;
        i=n;
        while(i>0){
            ans[w++]=i;
            i=par[i];
        }
        for(i=w-1;i>=0;i--) printf("%d ",ans[i]);printf("\n");
    }
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( min[ver] != INT_MAX )
            {
                if( temp->wt + min[ver] < min[temp->v] )
                {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
                }
            }
            else
                break;
            temp = temp->next;
        }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int k = 0;
int a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}