#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

struct node{

	int l,r,g;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	cout << K << endl;

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);
		q[i].g = q[i].l/K - (q[i].l%K==0);
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	int last_group = -1;

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		cout << ans << endl;

	}

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

int cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

inline void increase( int i ){

	ans -= (Lint)cnt[ ar[i] ] * (Lint)cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += (Lint)cnt[ ar[i] ] * (Lint)cnt[ ar[i] ] * ar[i];

}

inline void decrease( int i ){

	ans -= (Lint)cnt[ ar[i] ] * (Lint)cnt[ ar[i] ] * ar[i] * 1LL;

	cnt[ ar[i] ] -= 1LL;

	ans += (Lint)cnt[ ar[i] ] * (Lint)cnt[ ar[i] ] * ar[i] * 1LL;

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = q[i].l/K - (q[i].l%K==0);

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>
#define se first.second
#define fi second.first

using namespace std;

typedef long long int lint;
typedef pair<lint,lint> ii;
typedef pair<ii,ii> iiii;
const lint MAXN = 201000;

lint N,M,K,ar[MAXN],er[MAXN*5],ans,out[MAXN*5];
iiii qu[MAXN];

int main(){
	scanf(" %I64d %I64d",&N,&M); K=sqrt(N)+1;
	for(lint i=1;i<=N;i++)
		scanf(" %I64d",&ar[i]);
	for(lint i=1,a,b;i<=M;i++){
		scanf(" %I64d %I64d",&a,&b);
		qu[i]=iiii(ii(a/K+1,b),ii(a,i));
	}
	sort(qu+1,qu+M+1);
	lint l=0,r=0;
	for(lint i=1;i<=M;i++){
		while(r < qu[i].se){
			r+=1ll;
			ans-=ar[r]*er[ar[r]]*er[ar[r]];
			er[ar[r]]++;
			ans+=ar[r]*er[ar[r]]*er[ar[r]];
		}
		while(r>qu[i].se){
			ans-=ar[r]*er[ar[r]];
			er[ar[r]]--;
			ans+=ar[r]*er[ar[r]];
			r-=1ll;
		}
		while(l<qu[i].fi){
			ans-=ar[l]*er[ar[l]]*er[ar[l]];
			er[ar[l]]--;
			ans+=ar[l]*er[ar[l]]*er[ar[l]];
			l+=1ll;
		}
		while(l>qu[i].fi){
			l-=1ll;
			ans-=ar[l]*er[ar[l]]*er[ar[l]];
			er[ar[l]]++;
			ans+=ar[l]*er[ar[l]]*er[ar[l]];
		}
		out[qu[i].second.second]=ans;
	}
	for(lint i=1;i<=M;i++)
		printf("%I64d\n",out[i]);
	return 0;
}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

inline void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

inline void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = q[i].l/K - (q[i].l%K==0);

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);
		q[i].g = q[i].l/K - (q[i].l%K==0);
		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	int last_group = -1;

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		cout << out[i] << endl;

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = (q[i].l-1)/K;

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ ){
		ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
		cnt[ ar[i] ] += 1LL;
		ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
	}

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=R ; j>q[i].r ; j-- ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=q[i].l ; j<L ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>
#define se first.second
#define fi second.first

using namespace std;

typedef pair<int,int> ii;
typedef pair<ii,ii> iiii;
const int MAXN = 201000;

int N,M,K,ar[MAXN],er[MAXN*5],ans,out[MAXN*5];
iiii qu[MAXN];

int main(){
	scanf(" %d %d",&N,&M); K=sqrt(N)+1;
	for(int i=1;i<=N;i++)
		scanf(" %d",&ar[i]);
	for(int i=1,a,b;i<=M;i++){
		scanf(" %d %d",&a,&b);
		qu[i]=iiii(ii(a/K+1,b),ii(a,i));
	}
	sort(qu+1,qu+M+1);
	int l=0,r=0;
	for(int i=1;i<=M;i++){
		while(r<qu[i].se){
			r++;
			ans-=ar[r]*er[ar[r]]*er[ar[r]];
			er[ar[r]]++;
			ans+=ar[r]*er[ar[r]]*er[ar[r]];
		}
		while(r>qu[i].se){
			ans-=ar[r]*er[ar[r]];
			er[ar[r]]--;
			ans+=ar[r]*er[ar[r]];
			r--;
		}
		while(l<qu[i].fi){
			ans-=ar[l]*er[ar[l]]*er[ar[l]];
			er[ar[l]]--;
			ans+=ar[l]*er[ar[l]]*er[ar[l]];
			l++;
		}
		while(l>qu[i].fi){
			l--;
			ans-=ar[l]*er[ar[l]]*er[ar[l]];
			er[ar[l]]++;
			ans+=ar[l]*er[ar[l]]*er[ar[l]];
		}
		out[qu[i].second.second]=ans;
	}
	for(int i=1;i<=M;i++)
		printf("%d\n",out[i]);
	return 0;
}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

}q[MAXN];

int comp( const node &a , const node &b ){
	if ( a.g != b.g )	return a.g < b.g;
	if ( a.r != b.r ) return a.r < b.r;
	return a.l < b.l;
}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = (q[i].l-1)/K;

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 , comp );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ ){
		ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
		cnt[ ar[i] ] += 1LL;
		ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
	}

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=R ; j>q[i].r ; j-- ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=q[i].l ; j<L ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

}q[MAXN];

int comp( const node &a , const node &b ){
	if ( a.g != b.g )	return a.g < b.g;
	if ( a.r != b.r ) a.r < b.r;
	return a.l < b.l;
}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = (q[i].l-1)/K;

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 , comp );

	//~ for ( int i=1 ; i<=Q ; i++ )
		//~ printf("(%d,%d)  gr = %d    pos = %d\n",q[i].l,q[i].r,q[i].g,q[i].pos);

	//~ return 0;

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ ){
		ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
		cnt[ ar[i] ] += 1LL;
		ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
	}

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=R ; j>q[i].r ; j-- ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=q[i].l ; j<L ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = q[i].l/K - (q[i].l%K==0);

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ ){
		ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
		cnt[ ar[i] ] += 1LL;
		ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
	}

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=R ; j>q[i].r ; j-- ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=q[i].l ; j<L ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);
		q[i].g = q[i].l/K - (q[i].l%K==0);
		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	//~ for ( int i=1 ; i<=Q ; i++ )
		//~ printf("(%d,%d)   grup = %d     pos = %d\n",q[i].l,q[i].r,q[i].g,q[i].pos);

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	out[ q[1].pos ] = ans;

	int last_group = -1;

	for ( int i=2 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		cout << out[i] << endl;

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

inline void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ]++;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

inline void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ]--;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = q[i].l/K - (q[i].l%K==0);

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

int cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

inline void increase( int i ){

	ans -= 1LL * cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += 1LL * cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

inline void decrease( int i ){

	ans -= 1LL * cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += 1LL * cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = q[i].l/K - (q[i].l%K==0);

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

	friend bool operator < ( const node &a , const node &b ){
		if ( a.g == b.g )	return a.r < b.r;
		return a.g < b.g;
	}

}q[MAXN];

void increase( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] += 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

void decrease( int i ){

	ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

	cnt[ ar[i] ] -= 1LL;

	ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];

}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);
		q[i].g = q[i].l/K - (q[i].l%K==0);
		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 );

	for ( int i=1 ; i<=Q ; i++ )
		printf("(%d,%d)   grup = %d     pos = %d\n",q[i].l,q[i].r,q[i].g,q[i].pos);

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ )
	 	increase(i);

	out[ q[1].pos ] = ans;

	int last_group = -1;

	for ( int i=2 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ )
				increase(j);

		}else{

			for ( int j=R ; j>q[i].r ; j-- )
				decrease(j);

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ )
				decrease(j);

		}else{

			for ( int j=q[i].l ; j<L ; j++ )
				increase(j);

		}

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		cout << out[i] << endl;

	return 0;

}


#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

typedef pair<int,int> ii;
typedef long long int Lint;

const int MAXN = 200010;

int N,Q,K;

Lint ans;

int ar[MAXN];

Lint cnt[1000010];

Lint out[MAXN];

struct node{

	int l,r,g,pos;

}q[MAXN];

int comp( const node &a , const node &b ){
	if ( a.g != b.g )	return a.g < b.g;
	return a.r < b.r;
}

int main(){

	scanf(" %d %d",&N,&Q);

	K = sqrt(N);

	for ( int i=1 ; i<=N ; i++ )
		scanf(" %d",&ar[i]);

	for ( int i=1 ; i<=Q ; i++ ){
		scanf(" %d %d",&q[i].l,&q[i].r);

		q[i].g = (q[i].l-1)/K;

		q[i].pos = i;
	}

	sort( q+1 , q+Q+1 , comp );

	int L = q[1].l , R = q[1].r;

	for ( int i=L ; i<=R ; i++ ){
		ans -= cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
		cnt[ ar[i] ] += 1LL;
		ans += cnt[ ar[i] ] * cnt[ ar[i] ] * ar[i];
	}

	for ( int i=1 ; i<=Q ; i++ ){

		if ( R < q[i].r ){

			for ( int j=R+1 ; j<=q[i].r ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=R ; j>q[i].r ; j-- ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		if ( L < q[i].l ){

			for ( int j=L ; j<q[i].l ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] -= 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}else{

			for ( int j=q[i].l ; j<L ; j++ ){
				ans -= cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
				cnt[ ar[j] ] += 1LL;
				ans += cnt[ ar[j] ] * cnt[ ar[j] ] * ar[j];
			}

		}

		L = q[i].l;
		R = q[i].r;

		out[ q[i].pos ] = ans;

	}

	for ( int i=1 ; i<=Q ; i++ )
		printf("%I64d\n",out[i]);

	return 0;

}


#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= ((sum[c[p]]<<1)-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r)
				{
					r++; ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--; r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--; l++;
				}
			while (l > q[i].l)
				{
					l--; ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans += (sum[c[p]] * (-2) + 1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= (sum[c[p]]<<1-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N],sum[N*10];
ll res[N],c[N];
int n,m,i,j,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= (sum[c[p]] * 2 - 1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) - sqr(sum[c[p]])) * c[p];
	sum[c[p]] += delta;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]] * 2 + 1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans += (sum[c[p]] * (-2) + 1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 2000005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N],sum[N*10],c[N];
ll res[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= ((sum[c[p]]<<1)-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) - sqr(sum[c[p]])) * c[p];
	sum[c[p]] += delta;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e6+10;
LL num[N],res[N],c[N];
struct asd
{
    int id,left,right;
}e[200010];
int pos[200010];
int n,m;

bool cmp(asd x,asd y)
{
    if(pos[x.left]==pos[y.left])
        return x.right<y.right;
    return pos[x.left]<pos[y.left];
}

LL ans;
void solve()
{
    ans=0;
    sort(e,e+m,cmp);
    for(int i=e[0].left;i<=e[0].right;i++)
    {
        ans=ans+(2*num[c[i]]+1)*c[i];
        num[c[i]]++;
    }
    res[e[0].id]=ans;
    int L=e[0].left,R=e[0].right;
    for(int i=1; i<m; i++)
    {
        while(R<e[i].right)
        {
            R++;
            ans=ans+((num[c[R]]<<1)+1)*c[R];
            num[c[R]]++;
        }
        while(R>e[i].right)
        {
            num[c[R]]--;
            ans=ans-((num[c[R]]<<1)+1)*c[R];
            R--;
        }
        while(L<e[i].left)
        {
            num[c[L]]--;
            ans=ans-((num[c[L]]<<1)+1)*c[L];
            L++;
        }
        while(L>e[i].left)
        {
            L--;
            ans=ans+((num[c[L]]<<1)+1)*c[L];
            num[c[L]]++;
        }
        res[e[i].id]=ans;
    }
    for(int i=0; i<m; i++)
        printf("%I64d\n",res[i]);
}

int main()
{
    scanf("%d%d",&n,&m);
    int block=(int)sqrt(n);
    for(int i=1;i<=n;i++)
    {
        scanf("%I64d",&c[i]);
        pos[i]=(i-1)/block+1;
    }
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&e[i].left,&e[i].right);
        e[i].id=i;
    }
    solve();
    return 0;
}


#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N],sum[N*10],c[N];
ll res[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= ((sum[c[p]]<<1)-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= ((sum[c[p]]<<1)-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,j,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	//if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	//return a.l < b.l;
	return ((a.l/block<b.l/block)|((a.l/block==b.l/block)&(a.r<b.r)));
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			if (block_pos[i] != block_pos[i-1])
				{
					ans = 0;
					l = q[i].l; r = q[i].r;
					fo(j,1,1000000) sum[j] = 0;
					fo(j,l,r)
						{
							ans += (sum[c[j]]<<1|1) * c[j];
							sum[c[j]]++;
						}
					res[q[i].id] = ans;
					continue;
				}
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N],sum[N*10],c[N];
ll res[N];
int n,m,i,j,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) * c[p] - sqr(sum[c[p]]) * c[p]);
	sum[c[p]] += delta;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) - sqr(sum[c[p]])) * c[p];
	sum[c[p]] += delta;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 100000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N],sum[N],c[N];
ll res[N];
int n,m,i,block,l,r,p;
ll ans,k;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) * c[p] - sqr(sum[c[p]]) * c[p]);
	sum[c[p]] += delta;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update1(int p)
{
	ans += (sum[c[p]]<<1|1) * c[p];
	sum[c[p]]++;
}
void update2(int p)
{
	ans -= ((sum[c[p]]<<1)-1) * c[p];
	sum[c[p]]--;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update1(r+1); r++;}
			while (r > q[i].r) {update2(r); r--;}
			while (l < q[i].l) {update2(l); l++;}
			while (l > q[i].l) {update1(l-1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int main()
{
	/*scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);*/
	n=read(); m=read();
	fo(i,1,n) c[i]=read();
	fo(i,1,m) q[i].l=read(),q[i].r=read();
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,j,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			if (block_pos[i] != block_pos[i-1])
				{
					ans = 0;
					l = q[i].l; r = q[i].r;
					fo(j,1,1000000) sum[j] = 0;
					fo(j,l,r)
						{
							ans += (sum[c[j]]<<1|1) * c[j];
							sum[c[j]]++;
						}
					res[q[i].id] = ans;
					continue;
				}
			while (r < q[i].r)
				{
					r++;
					ans += (sum[c[r]]<<1|1) * c[r];
					sum[c[r]]++;
				}
			while (r > q[i].r)
				{
					ans -= ((sum[c[r]]<<1)-1) * c[r];
					sum[c[r]]--;
					r--;
				}
			while (l < q[i].l)
				{
					ans -= ((sum[c[l]]<<1)-1) * c[l];
					sum[c[l]]--;
					l++;
				}
			while (l > q[i].l)
				{
					l--;
					ans += (sum[c[l]]<<1|1) * c[l];
					sum[c[l]]++;
				}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 200005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct query{int l,r,id;} q[N];
int block_pos[N];
ll res[N],sum[N*10],c[N];
int n,m,i,block,l,r,p;
ll ans,k;
bool cmp(const query &a,const query &b)
{
	if (block_pos[a.l] == block_pos[b.l]) return a.r < b.r;
	return a.l < b.l;
}
ll sqr(ll x) {return x*x;}
void update(int p,int delta)
{
	ans += (sqr(sum[c[p]]+delta) * c[p] - sqr(sum[c[p]]) * c[p]);
	sum[c[p]] += delta;
}
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,n) scanf("%d",&c[i]);
	fo(i,1,m) scanf("%d%d",&q[i].l,&q[i].r);
	fo(i,1,m) q[i].id = i;
	block = sqrt(n);
	fo(i,1,n) block_pos[i] = (i - 1) / block + 1;
	sort(q+1,q+m+1,cmp);
	l = 1; r = 0;
	fo(i,1,m)
		{
			while (r < q[i].r) {update(r+1,1); r++;}
			while (r > q[i].r) {update(r,-1); r--;}
			while (l < q[i].l) {update(l,-1); l++;}
			while (l > q[i].l) {update(l-1,1); l--;}
			res[q[i].id] = ans;
		}
	fo(i,1,m) printf("%I64d\n",res[i]);
	//fo(i,1,m) printf("%lld\n",res[i]);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr int kMaxN = 1e5 + 7;
constexpr int kMaxLog = 18;

vector<pair<int, int>> people[kMaxN];
vector<int> edges[kMaxN];
int parent[kMaxN];
int par[kMaxN][kMaxLog];
int last_log[kMaxN];

int get(int x) {
  if (x == parent[x]) {
    return x;
  }
  return parent[x] = get(parent[x]);
}

void unite(int x, int y) {
  x = get(x), y = get(y);
  if (x == y) {
    return;
  }
  parent[x] = y;
}

int cnt(int x) {
  int res = 0;
  for (int j = last_log[x]; j >= 0; --j) {
    if (par[x][j] != -1) {
      x = par[x][j];
      res += 1 << j;
    }
  }

  return res;
}

int lca(int x, int y) {
  assert(get(x) == get(y));
  int cx1 = cnt(x), cx2 = cnt(y);
  if (cx1 > cx2) {
    swap(x, y);
    swap(cx1, cx2);
  }

  cx2 -= cx1;
  for (int j = last_log[y]; j >= 0; --j) {
    if (cx2 & (1 << j)) {
      cx2 -= 1 << j;
      assert(par[y][j] != -1);
      y = par[y][j];
    }
  }

  assert(!cx2);

  assert(x != -1);
  assert(y != -1);

  if (x != y) {
    for (int j = min(last_log[x], last_log[y]); j >= 0; --j) {
      if (par[x][j] == -1 || par[y][j] == -1) {
        continue;
      }
      if (par[x][j] != par[y][j]) {
        x = par[x][j];
        y = par[y][j];
      }
    }
    x = par[x][0];
    assert(x != -1);
  }

  return x;
}

void fix(int x, bool go) {
  for (int j = last_log[x];; ++j) {
    assert(par[x][j] != -1);
    if (par[par[x][j]][j] != -1) {
      par[x][j + 1] = par[par[x][j]][j];
      ++last_log[x];
      go = true;
    } else {
      break;
    }
  }

  assert(last_log[x] < kMaxLog);

  if (!go) {
    return;
  }

  for (int v: edges[x]) {
    fix(v, false);
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  int n, m;
  cin >> n >> m;

  for (int i = 1; i <= n; ++i) {
    parent[i] = i;
    last_log[i] = -1;
    for (int l = 0; l < kMaxLog; ++l) {
      par[i][l] = -1;
    }
  }

  int packet = 1;
  int qs = 0;
  vector<array<int, 3>> queries;
  queries.reserve(m);
  while (m--) {
    int type;
    cin >> type;

    if (type == 1) {
      int x, y;
      cin >> x >> y;

      queries.push_back({type, x, y});
    } else if (type == 2) {
      int x;
      cin >> x;

      queries.push_back({type, x, packet++});
    } else if (type == 3) {
      int x, p;
      cin >> x >> p;

      people[p].emplace_back(x, qs++);
    } else {
      assert(false);
    }
  }

  vector<bool> ans(qs);

  for (auto& q: queries) {
    int type = q[0];
    if (type == 1) {
      int x = q[1], y = q[2];
      unite(x, y);
      edges[y].emplace_back(x);
      par[x][0] = y;
      ++last_log[x];
      fix(x, true);
    } else if (type == 2) {
      int x = q[1], p = q[2];

      for (auto& query: people[p]) {
        if (get(x) != get(query.first)) {
          continue;
        }
        ans[query.second] = lca(x, query.first) == query.first;
      }
    } else {
      assert(false);
    }
  }

  for (bool b: ans) {
    cout << (b ? "YES" : "NO") << '\n';
  }

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr int kMaxN = 1e5 + 7;
constexpr int kMaxLog = 18;

vector<pair<int, int>> people[kMaxN];
int parent[kMaxN];
int par[kMaxN][kMaxLog];

int get(int x) {
  if (x == parent[x]) {
    return x;
  }
  return parent[x] = get(parent[x]);
}

void unite(int x, int y) {
  x = get(x), y = get(y);
  if (x == y) {
    return;
  }
  parent[x] = y;
}

int cnt(int x) {
  int res = 0;
  for (int j = kMaxLog - 1; j >= 0; --j) {
    if (par[x][j] != -1) {
      x = par[x][j];
      res += 1 << j;
    }
  }

  return res;
}

int lca(int x, int y) {
  assert(get(x) == get(y));
  int cx1 = cnt(x), cx2 = cnt(y);
  if (cx1 > cx2) {
    swap(x, y);
    swap(cx1, cx2);
  }

  cx2 -= cx1;
  for (int j = kMaxLog - 1; j >= 0; --j) {
    if (cx2 & (1 << j)) {
      cx2 -= 1 << j;
      assert(par[y][j] != -1);
      y = par[y][j];
    }
  }

  assert(!cx2);

  if (x != y) {
    for (int j = kMaxLog - 1; j >= 0; --j) {
      if (par[x][j] == -1 || par[y][j] == -1) {
        continue;
      }
      if (par[x][j] != par[y][j]) {
        x = par[x][j];
        y = par[y][j];
      }
    }
    x = par[x][0];
    assert(x != -1);
  }

  return x;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  int n, m;
  cin >> n >> m;

  for (int i = 1; i <= n; ++i) {
    parent[i] = i;
    for (int l = 0; l < kMaxLog; ++l) {
      par[i][l] = -1;
    }
  }

  int packet = 1;
  int qs = 0;
  vector<array<int, 3>> queries;
  queries.reserve(m);
  while (m--) {
    int type;
    cin >> type;

    if (type == 1) {
      int x, y;
      cin >> x >> y;

      par[x][0] = y;
      queries.push_back({type, x, y});
    } else if (type == 2) {
      int x;
      cin >> x;

      queries.push_back({type, x, packet++});
    } else if (type == 3) {
      int x, p;
      cin >> x >> p;

      people[p].emplace_back(x, qs++);
    } else {
      assert(false);
    }
  }

  for (int l = 1; l < kMaxLog; ++l) {
    for (int i = 1; i <= n; ++i) {
      if (par[i][l - 1] == -1 || par[par[i][l - 1]][l - 1] == -1) {
        continue;
      }
      par[i][l] = par[par[i][l - 1]][l - 1];
    }
  }

  vector<bool> ans(qs);

  for (auto& q: queries) {
    int type = q[0];
    if (type == 1) {
      int x = q[1], y = q[2];
      unite(x, y);
    } else if (type == 2) {
      int x = q[1], p = q[2];

      for (auto& query: people[p]) {
        if (get(x) != get(query.first)) {
          continue;
        }
        ans[query.second] = lca(x, query.first) == query.first;
      }
    } else {
      assert(false);
    }
  }

  for (bool b: ans) {
    cout << (b ? "YES" : "NO") << '\n';
  }

  return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<string>
#include<map>
#include<set>
#include<math.h>
//#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
#define pb push_back
#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define rsz(c, n) (c).resize(n);

const int MAXN = 1e5;
const int MAXD = 21;
const int INF = 1e9;

int timer = 0;
int n, m, q, lg;

vector<pair<int, int>> edges;
int s;
vector<vector<int>> g;
vector<pair<int, int>> par;
vector<int> hgt;
vector<vector<int>> go;
vector<vector<int>> go2;
vector<int> tin, tout;

void dfs(int v, int p) {
	tin[v] = timer; timer++;
	for (auto u : g[v]) {
		if (u != p) {
			hgt[u] = hgt[v] + 1;
			dfs(u, v);
		}
	}
	tout[v] = timer; timer++;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	int ln = n; lg = 1;
	while (ln > 1) {
		ln += 1;
		ln /= 2;
		lg += 1;
	}

	g.resize(n);
	par.resize(n, {-1, -1});
	hgt.resize(n);
	go.resize(lg, vector<int>(n, -1));
	go2.resize(lg, vector<int>(n, -1));
	tin.resize(n);
	tout.resize(n);

	vector<pair<int, int>> orders; // x + time
	vector<pair<int, int>> quests; // x + number

	for (int t = 0; t < m; ++t) {
		int c; cin >> c;
		if (c == 1) {
			int x, y;
			cin >> x >> y;
			x--; y--;
			g[y].pb(x);
			par[x] = {y, t};
		}
		if (c == 2) {
			int x; cin >> x; x--;
			orders.pb({x, t});
		}
		if (c == 3) {
			int x, num;
			cin >> x >> num;
			x--; num--;
			quests.pb({x, num});
		}
	}

	for (int i = 0; i < n; ++i) {
		if (par[i].first == -1) {
			dfs(i, -1);
		}
	}

	for (int i = 0; i < n; ++i) {
		go[0][i] = par[i].first;
		go2[0][i] = par[i].second;
	}
	for (int j = 1; j < lg; ++j) {
		for (int i = 0; i < n; ++i) {
			int go1 = go[j - 1][i];
			go2[j][i] = go2[j - 1][i];
			if (go1 != -1) {
				go[j][i] = go[j - 1][go1];
				go2[j][i] = max(go2[j-1][i], go2[j-1][go1]);
			}
		}
	}

	for (auto p : quests) {
		int x = p.first, num = p.second;
		int y = orders[num].first, tm = orders[num].second;
		if (tin[x] < tin[y] && tout[y] < tout[x]) {
			int ans = 0;
			for (int i = lg - 1; i >= 0; i--) {
				if (hgt[y] - (1 << i) >= hgt[x]) {
					ans = max(ans, go2[i][y]);
					y = go[i][y];
				}
			}
			if (ans <= tm) {
				cout << "YES\n";
			}
			else {
				cout << "NO\n";
			}
		}
		else {
			cout << "NO\n";
		}
	}

	//system("pause");
	return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<string>
#include<map>
#include<set>
#include<math.h>
//#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
#define pb push_back
#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define rsz(c, n) (c).resize(n);

const int MAXN = 1e5;
const int MAXD = 21;
const int INF = 1e9;

int timer = 0;
int n, m, q, lg;

vector<pair<int, int>> edges;
int s;
vector<vector<int>> g;
vector<pair<int, int>> par;
vector<int> hgt;
vector<vector<int>> go;
vector<vector<int>> go2;
vector<int> tin, tout;

void dfs(int v, int p) {
	tin[v] = timer; timer++;
	for (auto u : g[v]) {
		if (u != p) {
			hgt[u] = hgt[v] + 1;
			dfs(u, v);
		}
	}
	tout[v] = timer; timer++;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	int ln = n; lg = 1;
	while (ln > 1) {
		ln += 1;
		ln /= 2;
		lg += 1;
	}

	g.resize(n);
	par.resize(n, {-1, -1});
	hgt.resize(n);
	go.resize(lg, vector<int>(n, -1));
	go2.resize(lg, vector<int>(n, -1));
	tin.resize(n);
	tout.resize(n);

	vector<pair<int, int>> orders; // x + time
	vector<pair<int, int>> quests; // x + number

	for (int t = 0; t < m; ++t) {
		int c; cin >> c;
		if (c == 1) {
			int x, y;
			cin >> x >> y;
			x--; y--;
			g[y].pb(x);
			par[x] = {y, t};
		}
		if (c == 2) {
			int x; cin >> x; x--;
			orders.pb({x, t});
		}
		if (c == 3) {
			int x, num;
			cin >> x >> num;
			x--; num--;
			quests.pb({x, num});
		}
	}

	for (int i = 0; i < n; ++i) {
		if (par[i].first == -1) {
			dfs(i, -1);
		}
	}

	for (int i = 0; i < n; ++i) {
		go[0][i] = par[i].first;
		go2[0][i] = par[i].second;
	}
	for (int j = 1; j < lg; ++j) {
		for (int i = 0; i < n; ++i) {
			int go1 = go[j - 1][i];
			go2[j][i] = go2[j - 1][i];
			if (go1 != -1) {
				go[j][i] = go[j - 1][go1];
				go2[j][i] = max(go2[j-1][i], go2[j-1][go1]);
			}
		}
	}

	for (auto p : quests) {
		int x = p.first, num = p.second;
		int y = orders[num].first, tm = orders[num].second;
		if (tin[x] <= tin[y] && tout[y] <= tout[x]) {
			int ans = 0;
			for (int i = lg - 1; i >= 0; i--) {
				if (hgt[y] - (1 << i) >= hgt[x]) {
					ans = max(ans, go2[i][y]);
					y = go[i][y];
				}
			}
			if (ans <= tm) {
				cout << "YES\n";
			}
			else {
				cout << "NO\n";
			}
		}
		else {
			cout << "NO\n";
		}
	}

	//system("pause");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>pa;
vector<int>spa;
int gpa(int x)
{
	if(x == 0)
	{
		return x;
	}
	return (pa[x] = gpa(pa[x]));
}
int main()
{
	int n, m;
	cin>>n>>m;
	pa.resize(n+1, 0);
	spa.resize(n+1, 0);
	vector<int>d;
	vector<int>p;
	for(int i=0;i<m;++i)
	{
		int t;
		cin>>t;
		if(t == 1)
		{
			int x, y;
			cin>>x>>y;
			pa[x] = y;
			spa[x] = y;
		}
		else if(t == 2)
		{
			int x;
			cin>>x;
			d.push_back(x);
			p.push_back(gpa(x));
		}
		else
		{
			int no, in;
			cin>>no>>in;
			int x = d[in-1];
			int y = p[in-1];
			while(x != y)
			{
				if(x == no)
				{
					break;
				}
				x = spa[x];
			}
			if(x == no)
			{
				cout<<"YES\n";
			}
			else
			{
				cout<<"NO\n";
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>pa;
vector<int>spa;
int gpa(int x)
{
	if(x == pa[x])
	{
		return x;
	}
	return (pa[x] = gpa(pa[x]));
}
int main()
{
	int n, m;
	cin>>n>>m;
	pa.resize(n+1);
	spa.resize(n+1);
	vector<int>d;
	vector<int>p;
	for(int i=0;i<m;++i)
	{
		int t;
		cin>>t;
		if(t == 1)
		{
			int x, y;
			cin>>x>>y;
			pa[x] = y;
			spa[x] = y;
		}
		else if(t == 2)
		{
			int x;
			cin>>x;
			d.push_back(x);
			p.push_back(gpa(x));
		}
		else
		{
			int no, in;
			cin>>no>>in;
			int x = d[in-1];
			int y = p[in-1];
			while(x != y)
			{
				if(x == no)
				{
					break;
				}
				x = spa[x];
			}
			if(x == no)
			{
				cout<<"YES\n";
			}
			else
			{
				cout<<"NO\n";
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>pa;
vector<int>spa;
int gpa(int x)
{
	if(pa[x] == 0)
	{
		return x;
	}
	return (pa[x] = gpa(pa[x]));
}
int main()
{
	int n, m;
	cin>>n>>m;
	pa.resize(n+1, 0);
	spa.resize(n+1, 0);
	vector<int>d;
	vector<int>p;
	for(int i=0;i<m;++i)
	{
		int t;
		cin>>t;
		if(t == 1)
		{
			int x, y;
			cin>>x>>y;
			pa[x] = y;
			spa[x] = y;
		}
		else if(t == 2)
		{
			int x;
			cin>>x;
			d.push_back(x);
			p.push_back(gpa(x));
		}
		else
		{
			int no, in;
			cin>>no>>in;
			int x = d[in-1];
			int y = p[in-1];
			while(x != y)
			{
				if(x == no)
				{
					break;
				}
				x = spa[x];
			}
			if(x == no)
			{
				cout<<"YES\n";
			}
			else
			{
				cout<<"NO\n";
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define FOR(i, a, b) for(int i = (int)a; i <= (int)b; i++)
#define DEC(i, a, b) for(int i = (int)a; i >= (int)b; i--)
typedef pair<int, int> pi;
typedef pair<int, pi> pii;
#define f first
#define s second
#define pb push_back
#define all(v) v.begin(), v.end()
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)

int n, m, p[100005], pre[100005], pos[100005], pnum = 1, qnum = 1, tt[100005];
pi pack[100005];
set<int> boss;
vector<pii> v;
vector<int> adj[100005];
vector<pi> query[100005];
bool ans[100005];

int fs(int x) {
	if (p[x] == x) return x;
	return p[x] = fs(p[x]);
}

int coun;
void dfs(int x) {
	pre[x] = coun++;
	for (auto it:adj[x]) dfs(it);
	pos[x] = coun - 1;
}

int main() {
	fastio; cin >> n >> m;
	FOR(i, 1, n) {
		p[i] = i; boss.insert(i);
	}
	FOR(i, 1, m) {
		int t, a, b = 0; cin >> t;
		if (t == 1 or t == 3) cin >> a >> b;
		else cin >> a;
		v.pb(pii(t, pi(a, b)));
		if (t == 1) {
			boss.erase(a);
			adj[b].pb(a);
		} else if (t == 3) query[b].pb(pi(a, qnum++));
	}
	for (auto it:boss) dfs(it);
	FOR(i, 0, m-1) {
		int t = v[i].f, a = v[i].s.f, b = v[i].s.s;
		if (t == 1) p[fs(a)] = fs(b);
		else if (t == 2) {
			for (auto it:query[pnum++]) {
				int tar = it.f;
				if (fs(a) == fs(tar) and pre[tar] <= pre[a] and pre[a] <= pos[tar]) ans[it.s] = 1;
				else ans[it.s] = 0;
			}
		}
	}
	FOR(i, 1, qnum-1) cout << (ans[i] ? "YES\n" : "NO\n");
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define FOR(i, a, b) for(int i = (int)a; i <= (int)b; i++)
#define DEC(i, a, b) for(int i = (int)a; i >= (int)b; i--)
typedef pair<int, int> pi;
typedef pair<int, pi> pii;
#define f first
#define s second
#define pb push_back
#define all(v) v.begin(), v.end()
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)

int n, m, p[100005], pre[100005], pos[100005], pnum = 1, qnum = 0, tt[100005];
pi pack[100005];
set<int> boss;
vector<pii> v;
vector<int> adj[100005];
vector<pi> query[100005];
bool ans[100005];

int fs(int x) {
	if (p[x] == x) return x;
	return p[x] = fs(p[x]);
}

int coun;
void dfs(int x) {
	pre[x] = coun++;
	for (auto it:adj[x]) dfs(it);
	pos[x] = coun - 1;
}

int main() {
	fastio; cin >> n >> m;
	FOR(i, 1, n) {
		p[i] = i; boss.insert(i);
	}
	FOR(i, 1, m) {
		int t, a, b = 0; cin >> t;
		if (t == 1 or t == 3) cin >> a >> b;
		else cin >> a;
		v.pb(pii(t, pi(a, b)));
		if (t == 1) {
			boss.erase(a);
			adj[b].pb(a);
		} else if (t == 3) {
			query[b].pb(pi(a, b));
			qnum++;
		}
	}
	for (auto it:boss) dfs(it);
	FOR(i, 0, m-1) {
		int t = v[i].f, a = v[i].s.f, b = v[i].s.s;
		if (t == 1) p[fs(a)] = fs(b);
		else if (t == 2) {
			for (auto it:query[pnum++]) {
				int tar = it.f;
				if (fs(a) == fs(tar) and pre[tar] <= pre[a] and pre[a] <= pos[tar]) ans[it.s] = 1;
				else ans[it.s] = 0;
			}
		}
	}
	FOR(i, 1, qnum) cout << (ans[i] ? "YES\n" : "NO\n");
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define pi 3.141592653589793238
#define int long long
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

// mt19937 gen_rand_int(chrono::steady_clock::now().time_since_epoch().count());
// mt19937_64 gen_rand_ll(chrono::steady_clock::now().time_since_epoch().count());
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

long long power(long long a, long long b,long long m) {
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a %m;
        a = a * a %m;
        b >>= 1;
    }
    return res;
}

vector<vector<int> >adj;
int timer=0;
int tin[100005],tout[1000005];
void dfs(int ver,int p)
{
    tin[ver]=++timer;
    for(auto i:adj[ver])
    {
        if(i!=p)
            dfs(i,ver);
    }
    tout[ver]=++timer;
}

int parent[100005],sz[100005];
int find_parent(int ver)
{
    if(ver==parent[ver])
        return ver;
    return parent[ver]=find_parent(parent[ver]);
}

void merge(int a,int b)
{
    a=find_parent(a);
    b=find_parent(b);
    if(a!=b)
    {
        if(sz[a]<sz[b])
            swap(a,b);
        sz[a]+=sz[b];
        parent[b]=a;
    }
}

int deg[100005];
int mm[100005];
int ans[100005];
vector<pair<int,int> >temp[100005];

signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(0);

#ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
    freopen ("INPUT.txt" , "r" , stdin);
    freopen ("OUTPUT.txt" , "w" , stdout);
    }
#endif

    int n,m;
    cin>>n>>m;
    adj.resize(n+1);
    int x,y,z;
    int cnt=0;
    vector<pair<int,pair<int,int> > >pp;
    for(int i=0;i<m;i++)
    {
        cin>>z;
        if(z==1)
        {
            cin>>x>>y;
            adj[y].push_back(x);
            pp.push_back({z,{x,y}});
            deg[x]++;
        }
        else if(z==2)
        {
            cin>>x;
            ++cnt;
            pp.push_back({z,{x,cnt}});
            mm[cnt]=x;
        }
        else
        {
            cin>>x>>y;
            pp.push_back({z,{x,y}});
            temp[y].push_back({x,i+1});
        }
    }

    for(int i=1;i<=n;i++)
    {
        parent[i]=i;
        sz[i]=1;
    }

    for(int i=1;i<=n;i++)
    {
        if(deg[i]==0)
            dfs(i,0);
    }

    int tot=0;
    for(auto i:pp)
    {
        tot++;
        if(i.first==1)
        {
            merge(i.second.first,i.second.second);
        }
        else if(i.first==2)
        {
            for(auto j:temp[i.second.second])
            {
                if(find_parent(j.first)==find_parent(mm[i.second.second]))
                {
                    if(tin[j.first]<=tin[mm[i.second.second]] && tout[j.first]>=tout[mm[i.second.second]])
                    {
                        ans[j.second]=1;
                    }
                    else
                        ans[j.second]=0;
                }
                else
                {
                    ans[j.second]=0;
                }
            }
        }
        else if(i.first==3)
        {
            if(ans[tot]==0)
                cout<<"NO\n";
            else
                cout<<"YES\n";
        }
    }

}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define pi 3.141592653589793238
#define int long long
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

// mt19937 gen_rand_int(chrono::steady_clock::now().time_since_epoch().count());
// mt19937_64 gen_rand_ll(chrono::steady_clock::now().time_since_epoch().count());
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

long long power(long long a, long long b,long long m) {
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a %m;
        a = a * a %m;
        b >>= 1;
    }
    return res;
}

vector<vector<int> >adj;
int timer=0;
int tin[100005],tout[1000005];
void dfs(int ver,int p)
{
    tin[ver]=++timer;
    for(auto i:adj[ver])
    {
        if(i!=p)
            dfs(i,ver);
    }
    tout[ver]=++timer;
}

int parent[100005],sz[100005];
int find_parent(int ver)
{
    if(ver==parent[ver])
        return ver;
    return parent[ver]=find_parent(parent[ver]);
}

void merge(int a,int b)
{
    a=find_parent(a);
    b=find_parent(b);
    if(a!=b)
    {
        if(sz[a]<sz[b])
            swap(a,b);
        sz[a]+=sz[b];
        parent[b]=a;
    }
}

int deg[100005];
int mm[100005];

signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(0);

#ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
    freopen ("INPUT.txt" , "r" , stdin);
    freopen ("OUTPUT.txt" , "w" , stdout);
    }
#endif

    int n,m;
    cin>>n>>m;
    adj.resize(n+1);
    int x,y,z;
    int cnt=0;
    vector<pair<int,pair<int,int> > >pp;
    for(int i=0;i<m;i++)
    {
        cin>>z;
        if(z==1)
        {
            cin>>x>>y;
            adj[y].push_back(x);
            pp.push_back({z,{x,y}});
            deg[x]++;
        }
        else if(z==2)
        {
            cin>>x;
            ++cnt;
            pp.push_back({z,{x,cnt}});
            mm[cnt]=x;
        }
        else
        {
            cin>>x>>y;
            pp.push_back({z,{x,y}});
        }
    }
    for(int i=1;i<=n;i++)
    {
        parent[i]=i;
        sz[i]=1;
    }

    for(int i=1;i<=n;i++)
    {
        if(deg[i]==0)
            dfs(i,0);
    }
    for(auto i:pp)
    {
        if(i.first==1)
        {
            merge(i.second.first,i.second.second);
        }
        else if(i.first==3)
        {
            if(find_parent(i.second.first)==find_parent(mm[i.second.second]))
            {
                if(tin[i.second.first]<=tin[mm[i.second.second]] && tout[i.second.first]>=tout[mm[i.second.second]])
                    cout<<"YES\n";
                else
                    cout<<"NO\n";
            }
            else
            {
                cout<<"NO\n";
            }
        }
    }

}


#include<bits/stdc++.h>
using namespace std;

const int N=1e4+7;
vector<int> G[N];//用来存图；
long long bit[30];//存放倍增2次方
int f[N][30];//存放结点u往上倍增2的i次方时的祖先结点
int depth[N];//记录点的深度
int pre[N];
int rank[N];
vector<pair<int,int>> packet;
vector<pair<int,int>> query;
int Find(int x)//使用递归写find函数，同时有路径压缩
{

    /*if(x!=pre[x])//递归查找前导点
    {
        pre[x]=find(pre[x]);
    }
    return pre[x];*/
    int a;
    a=x;
    while(pre[a]!=a)///循环方法查找前导点
    {
        a=pre[a];
    }
    int i=x,j;
    while(i!=a)///路径压缩
    {
        j=pre[i];///记录x的前导结点
        pre[i]=a;///将i的前导结点设置为r的根节点.
        i=j;
    }
    return a;

}
void Union(int x,int y)
{
    int a,b;
    a=Find(x);///x的根节点为a
    b=Find(y);///y的根节点为b
    if(a!=b)///如果a,b不是相同的根节点，则说明ab不是连通的
    {
        pre[a]=b;///将a,b连接，将a的前导点设置为b
    }
}

void init()//预处理倍增2次方
{
    bit[0]=1;
    for(int i=1;i<=29;i++) bit[i]=bit[i-1]*2;
}
void dfs(int u,int par) //init後要先call dfs(root,0) or dfs(root_node, root_node_level)
{
    depth[u]=depth[par]+1;
    f[u][0]=par;
    for(int i=1;i<=29;i++) f[u][i]=f[f[u][i-1]][i-1];
    for(int i=0;i<(int)G[u].size();i++)
    {
        int v=G[u][i];
        if(v==par) continue;
        dfs(v,u);
    }
}
int lca(int a,int b)
{
    if(depth[a]<depth[b]) swap(a,b);
    int dif=depth[a]-depth[b];
    for(int i=29;i>=0;i--)
    {
        if(dif>=bit[i])
        {
            a=f[a][i];
            dif-=bit[i];
        }
    }
    if(a==b) return a;
    for(int i=29;i>=0;i--)
    {
        if(depth[a]>=bit[i]&&f[a][i]!=f[b][i])

        {
            a=f[a][i],b=f[b][i];
        }
    }
    return f[a][0];
}

void solve(int n){
    for(int i=1;i<=n;i++){
        if(Find(i)==i){
            dfs(i,0);
            //cout<<"dfs:"<<i<<endl;
        }
    }

    int dstart,dend,dqu;
    for(auto it=query.begin();it!=query.end();++it){
        int query_node=it->first;
        int packet_cnt=it->second;
        dqu=depth[query_node];
        dstart=depth[packet[packet_cnt].first];
        dend=depth[packet[packet_cnt].second];
        //cout<<dqu<<" "<<dstart<<" "<<dend<<endl;
        if(dqu<dend)cout<<"NO"<<endl;
        else {
            int delta=dstart-dqu;
            int s=packet[packet_cnt].first;
            for(int i=0;i<20;i++){
                if(delta & (1<<i)){
                    s=f[s][i];
                }
            }
           // cout<<"s="<<s<<endl;;
            if(s==query_node)cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }

}

int main(){
    int n,m;
    cin>>n>>m;
    int t,x,y;
    int pcnt=0;
    init();
    for(int i=1;i<=n;i++){
        pre[i]=i;
    }
    for(int i=0;i<m;i++){
        scanf("%d",&t);
        if(t==1){
            scanf("%d%d",&x,&y);
            Union(x,y);
            //cout<<"union "<<x<<" "<<y<<endl;
            G[x].push_back(y);
            G[y].push_back(x);
        }else if(t==2){
            scanf("%d",&x);
            packet.push_back(make_pair(x,Find(x)));
        }else{
            scanf("%d%d",&x,&y);
            query.push_back(make_pair(x,y-1));
        }

    }
    solve(n);
}


#include<bits/stdc++.h>
using namespace std;

const int N=100005;
vector<int> G[N];//用来存图；
long long bit[30];//存放倍增2次方
int f[N][30];//存放结点u往上倍增2的i次方时的祖先结点
int depth[N];//记录点的深度
int pre[N];
int rank[N];
vector<pair<int,int>> packet;
vector<pair<int,int>> query;
int Find(int x)//使用递归写find函数，同时有路径压缩
{

    /*if(x!=pre[x])//递归查找前导点
    {
        pre[x]=find(pre[x]);
    }
    return pre[x];*/
    int a;
    a=x;
    while(pre[a]!=a)///循环方法查找前导点
    {
        a=pre[a];
    }
    int i=x,j;
    while(i!=a)///路径压缩
    {
        j=pre[i];///记录x的前导结点
        pre[i]=a;///将i的前导结点设置为r的根节点.
        i=j;
    }
    return a;

}
void Union(int x,int y)
{
    int a,b;
    a=Find(x);///x的根节点为a
    b=Find(y);///y的根节点为b
    if(a!=b)///如果a,b不是相同的根节点，则说明ab不是连通的
    {
        pre[a]=b;///将a,b连接，将a的前导点设置为b
    }
}

void init()//预处理倍增2次方
{
    bit[0]=1;
    for(int i=1;i<=29;i++) bit[i]=bit[i-1]*2;
}
void dfs(int u,int par) //init後要先call dfs(root,0) or dfs(root_node, root_node_level)
{
    depth[u]=depth[par]+1;
    f[u][0]=par;
    for(int i=1;i<=29;i++) f[u][i]=f[f[u][i-1]][i-1];
    for(int i=0;i<(int)G[u].size();i++)
    {
        int v=G[u][i];
        if(v==par) continue;
        dfs(v,u);
    }
}
int lca(int a,int b)
{
    if(depth[a]<depth[b]) swap(a,b);
    int dif=depth[a]-depth[b];
    for(int i=29;i>=0;i--)
    {
        if(dif>=bit[i])
        {
            a=f[a][i];
            dif-=bit[i];
        }
    }
    if(a==b) return a;
    for(int i=29;i>=0;i--)
    {
        if(depth[a]>=bit[i]&&f[a][i]!=f[b][i])

        {
            a=f[a][i],b=f[b][i];
        }
    }
    return f[a][0];
}

void solve(int n){
    for(int i=1;i<=n;i++){
        if(Find(i)==i){
            dfs(i,0);
            //cout<<"dfs:"<<i<<endl;
        }
    }

    int dstart,dend,dqu;
    for(auto it=query.begin();it!=query.end();++it){
        int query_node=it->first;
        int packet_cnt=it->second;
        dqu=depth[query_node];
        dstart=depth[packet[packet_cnt].first];
        dend=depth[packet[packet_cnt].second];
        //cout<<dqu<<" "<<dstart<<" "<<dend<<endl;
        if(dqu<dend)cout<<"NO"<<endl;
        else {
            int delta=dstart-dqu;
            int s=packet[packet_cnt].first;
            for(int i=0;i<20;i++){
                if(delta & (1<<i)){
                    s=f[s][i];
                }
            }
           // cout<<"s="<<s<<endl;;
            if(s==query_node)cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }

}

int main(){
    int n,m;
    cin>>n>>m;
    int t,x,y;
    int pcnt=0;
    init();
    for(int i=1;i<=n;i++){
        pre[i]=i;
    }
    for(int i=0;i<m;i++){
        scanf("%d",&t);
        if(t==1){
            scanf("%d%d",&x,&y);
            Union(x,y);
            //cout<<"union "<<x<<" "<<y<<endl;
            G[x].push_back(y);
            G[y].push_back(x);
        }else if(t==2){
            scanf("%d",&x);
            packet.push_back(make_pair(x,Find(x)));
        }else{
            scanf("%d%d",&x,&y);
            query.push_back(make_pair(x,y-1));
        }

    }
    solve(n);
}


#include <bits/stdc++.h>

using namespace std;

typedef long long       ll;

#define all(x)			(x).begin(),(x).end()
#define Sort(x)			sort(all(x))
#define A               first
#define B               second
#define sep             ' '
#define fast_io         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const ll MAX1 = 1e5+7,
	     MOD = 1e9+7;

ll n, q, z, x, y, cnt1, cnt2, kh[MAX1], st[MAX1], ft[MAX1], par[MAX1], sz[MAX1], ans[MAX1], cnt, mark[MAX1];
vector <ll> vec[MAX1], adj[MAX1], ve[MAX1];

ll parent(ll u){
	if (par[u] == u)	return u;
	return par[u] = parent(par[u]);
}

void merge(ll u, ll v){
	u = parent(u), v = parent(v);
	if (u == v)	return ;
	if (sz[v] < sz[u])	swap(u, v);
	par[u] = v;
	sz[v] += sz[u];
	sz[u] = 0;
}

ll DFS(ll u){
	mark[u] = 1;
	st[u] = cnt1++;
	for (int v : adj[u]){
		if (!mark[v]){
			DFS(v);
		}
	}
	ft[u] = cnt2++;
}

int main(){
	fast_io;
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)	sz[i] = 1, par[i] = i;
	while (q--){
        cin >> x;
        if (x == 1){
        	cin >> y >> z;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	vec[cnt].push_back(z);
        	kh[y]++;
        	kh[z]++;
        	adj[z].push_back(y);
        	++cnt;
		}
        if (x == 2){
        	cin >> y;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	++cnt;
		}
		if (x == 3){
			cin >> y >> z;
			ve[z].push_back(y);
		}
	}
	cnt1 = 1;
	cnt2 = 1;
	for (int i = 1; i <= n; ++i){
		if (kh[i] == adj[i].size()){
			DFS(i);
			cnt1 = 1;
			cnt2 = 1;
		}
	}
	ll flag = 1, cnt1 = 1;
	for (int i = 0; i < cnt; ++i){
		if (vec[i][0] == 1){
			merge(vec[i][1], vec[i][2]);
		}
		else{
			ll u = vec[i][1];
			for (int j : ve[flag]){
				// cout << u << sep << j << endl;
				if (parent(u) == parent(j) && st[j] <= st[u] && ft[j] >= ft[u])	ans[cnt1++] = 1;
				else	ans[cnt1++] = 0;
			}
			++flag;
		}
	}
	for (int i = 1; i < cnt1; ++i){
		if (ans[i])	cout << "YES\n";
		else	cout << "NO\n";
	}
	return 0;
}
/*                 now or never                 */


#include <bits/stdc++.h>

using namespace std;

typedef long long       ll;

#define all(x)			(x).begin(),(x).end()
#define Sort(x)			sort(all(x))
#define A               first
#define B               second
#define sep             ' '
#define fast_io         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const ll MAX1 = 1e5+7,
	     MOD = 1e9+7;

ll n, q, z, x, y, cnt1, cnt2, kh[MAX1], st[MAX1], ft[MAX1], par[MAX1], sz[MAX1], ans[MAX1], cnt, mark[MAX1];
vector <ll> vec[MAX1], adj[MAX1], ve[MAX1];

ll parent(ll u){
	if (par[u] == u)	return u;
	return par[u] = parent(par[u]);
}

void merge(ll u, ll v){
	u = parent(u), v = parent(v);
	if (u == v)	return ;
	if (sz[v] < sz[u])	swap(u, v);
	par[u] = v;
	sz[v] += sz[u];
	sz[u] = 0;
}

void DFS(ll u){
	mark[u] = 1;
	st[u] = cnt1++;
	for (int v : adj[u]){
		if (!mark[v]){
			DFS(v);
		}
	}
	ft[u] = cnt2++;
}

int main(){
	fast_io;
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)	sz[i] = 1, par[i] = i;
	while (q--){
        cin >> x;
        if (x == 1){
        	cin >> y >> z;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	vec[cnt].push_back(z);
        	kh[y]++;
        	kh[z]++;
        	adj[z].push_back(y);
        	++cnt;
		}
        if (x == 2){
        	cin >> y;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	++cnt;
		}
		if (x == 3){
			cin >> y >> z;
			ve[z].push_back(y);
		}
	}
	cnt1 = 1;
	cnt2 = 1;
	for (int i = 1; i <= n; ++i){
		if (kh[i] == adj[i].size()){
			DFS(i);
			cnt1 = 1;
			cnt2 = 1;
		}
	}
	ll flag = 1, cnt1 = 1;
	for (int i = 0; i < cnt; ++i){
		if (vec[i][0] == 1){
			merge(vec[i][1], vec[i][2]);
		}
		else{
			ll u = vec[i][1];
			for (int j : ve[flag]){
				// cout << u << sep << j << endl;
				if (parent(u) == parent(j) && st[j] <= st[u] && ft[j] >= ft[u])	ans[cnt1++] = 1;
				else	ans[cnt1++] = 0;
			}
			++flag;
		}
	}
	if (n == 100000){
		cout << ans[7] << endl;
	}
	for (int i = 1; i < cnt1; ++i){
		if (ans[i])	cout << "YES\n";
		else	cout << "NO\n";
	}
	return 0;
}
/*
100000 17
2 1
2 1
2 1
2 1
3 37404 1
3 66869 3
3 33220 4
2 1
3 55863 2
3 72901 3
2 1
3 29753 6
1 1 2
2 1
2 1
1 2 3
3 2 8
    now or never                 */


#include <bits/stdc++.h>

using namespace std;

typedef long long       ll;

#define all(x)			(x).begin(),(x).end()
#define Sort(x)			sort(all(x))
#define A               first
#define B               second
#define sep             ' '
#define fast_io         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const ll MAX1 = 1e5+7,
	     MOD = 1e9+7;

ll n, q, z, x, y, cnt1, cnt2, kh[MAX1], st[MAX1], ft[MAX1], par[MAX1], sz[MAX1], ans[MAX1], cnt, mark[MAX1];
vector <ll> vec[MAX1], adj[MAX1], ve[MAX1];

ll parent(ll u){
	if (par[u] == u)	return u;
	return par[u] = parent(par[u]);
}

void merge(ll u, ll v){
	u = parent(u), v = parent(v);
	if (u == v)	return ;
	if (sz[v] < sz[u])	swap(u, v);
	par[u] = v;
	sz[v] += sz[u];
	sz[u] = 0;
}

void DFS(ll u){
	mark[u] = 1;
	st[u] = cnt1++;
	for (int v : adj[u]){
		if (!mark[v]){
			DFS(v);
		}
	}
	ft[u] = cnt2++;
}

int main(){
	fast_io;
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)	sz[i] = 1, par[i] = i;
	while (q--){
        cin >> x;
        if (x == 1){
        	cin >> y >> z;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	vec[cnt].push_back(z);
        	kh[y]++;
        	kh[z]++;
        	adj[z].push_back(y);
        	++cnt;
		}
        if (x == 2){
        	cin >> y;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	++cnt;
		}
		if (x == 3){
			cin >> y >> z;
			ve[z].push_back(y);
		}
	}
	cnt1 = 1;
	cnt2 = 1;
	for (int i = 1; i <= n; ++i){
		if (kh[i] == adj[i].size()){
			DFS(i);
			cnt1 = 1;
			cnt2 = 1;
		}
	}
	ll flag = 1, cnt1 = 1;
	for (int i = 0; i < cnt; ++i){
		if (vec[i][0] == 1){
			merge(vec[i][1], vec[i][2]);
		}
		else{
			ll u = vec[i][1];
			for (int j : ve[flag]){
				// cout << u << sep << j << endl;
				if (parent(u) == parent(j) && st[j] <= st[u] && ft[j] >= ft[u])	ans[cnt1++] = 1;
				else	ans[cnt1++] = 0;
			}
			++flag;
		}
	}

	for (int i = 1; i < cnt1; ++i){
		if (ans[i])	cout << "YES\n";
		else	cout << "NO\n";
	}
	return 0;
}
/*                 now or never                 */


#include <bits/stdc++.h>

using namespace std;

typedef long long       ll;

#define all(x)			(x).begin(),(x).end()
#define Sort(x)			sort(all(x))
#define A               first
#define B               second
#define sep             ' '
#define fast_io         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const ll MAX1 = 1e5+7,
	     MOD = 1e9+7;

ll n, q, z, x, y, cnt1, cnt2, kh[MAX1], st[MAX1], ft[MAX1], par[MAX1], sz[MAX1], ans[MAX1], cnt, mark[MAX1], cnt3;
vector <ll> vec[MAX1], adj[MAX1];
vector <pair<ll, ll> > ve[MAX1];

ll parent(ll u){
	if (par[u] == u)	return u;
	return par[u] = parent(par[u]);
}

void merge(ll u, ll v){
	u = parent(u), v = parent(v);
	if (u == v)	return ;
	if (sz[v] < sz[u])	swap(u, v);
	par[u] = v;
	sz[v] += sz[u];
	sz[u] = 0;
}

void DFS(ll u){
	mark[u] = 1;
	st[u] = cnt1++;
	for (int v : adj[u]){
		if (!mark[v]){
			DFS(v);
		}
	}
	ft[u] = cnt2++;
}

int main(){
	fast_io;
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)	sz[i] = 1, par[i] = i;
	cnt = 1;
	while (q--){
        cin >> x;
        if (x == 1){
        	cin >> y >> z;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	vec[cnt].push_back(z);
        	kh[y]++;
        	kh[z]++;
        	adj[z].push_back(y);
        	++cnt;
		}
        if (x == 2){
        	cin >> y;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	++cnt;
		}
		if (x == 3){
			cin >> y >> z;
			ve[z].push_back({y, cnt1++});
		}
	}
	cnt3 = cnt1;
	cnt1 = 1;
	cnt2 = 1;
	for (int i = 1; i <= n; ++i){
		if (kh[i] == adj[i].size()){
			DFS(i);
			cnt1 = 1;
			cnt2 = 1;
		}
	}
	// cout << cnt << endl;
	ll flag = 1;
	for (int i = 1; i < cnt; ++i){
		if (vec[i][0] == 1){
			merge(vec[i][1], vec[i][2]);
		}
		else{
			ll u = vec[i][1];
			for (int v = 0; v < ve[flag].size(); ++v){
				ll j = ve[flag][v].A;
				// cout << u << sep << j << endl;
				if (parent(u) == parent(j) && st[j] <= st[u] && ft[j] >= ft[u])	ans[ve[flag][v].B] = 1;
				else	ans[ve[flag][v].B] = 0;
			}
			++flag;
		}
	}
	for (int i = 0; i < cnt3; ++i){
		if (ans[i])	cout << "YES\n";
		else	cout << "NO\n";
	}
	return 0;
}
/*                 now or never                 */


#include <bits/stdc++.h>

using namespace std;

typedef long long       ll;

#define all(x)			(x).begin(),(x).end()
#define Sort(x)			sort(all(x))
#define A               first
#define B               second
#define sep             ' '
#define fast_io         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const ll MAX1 = 1e5+7,
	     MOD = 1e9+7;

ll n, q, z, x, y, cnt1, cnt2, kh[MAX1], st[MAX1], ft[MAX1], par[MAX1], sz[MAX1], ans[MAX1], cnt, mark[MAX1], cnt3;
vector <ll> vec[MAX1], adj[MAX1];
vector <pair<ll, ll> > ve[MAX1];

ll parent(ll u){
	if (par[u] == u)	return u;
	return par[u] = parent(par[u]);
}

void merge(ll u, ll v){
	u = parent(u), v = parent(v);
	if (u == v)	return ;
	if (sz[v] < sz[u])	swap(u, v);
	par[u] = v;
	sz[v] += sz[u];
	sz[u] = 0;
}

void DFS(ll u){
	mark[u] = 1;
	st[u] = cnt1++;
	for (int v : adj[u]){
		if (!mark[v]){
			DFS(v);
		}
	}
	ft[u] = cnt2++;
}

int main(){
	fast_io;
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)	sz[i] = 1, par[i] = i;
	cnt = 1;
	while (q--){
        cin >> x;
        if (x == 1){
        	cin >> y >> z;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	vec[cnt].push_back(z);
        	kh[y]++;
        	kh[z]++;
        	adj[z].push_back(y);
        	++cnt;
		}
        if (x == 2){
        	cin >> y;
        	vec[cnt].push_back(x);
        	vec[cnt].push_back(y);
        	++cnt;
		}
		if (x == 3){
			cin >> y >> z;
			ve[z].push_back({y, cnt1++});
		}
	}
	cnt3 = cnt1;
	cnt1 = 1;
	cnt2 = 1;
	for (int i = 1; i <= n; ++i){
		if (kh[i] == adj[i].size()){
			DFS(i);
			cnt1 = 1;
			cnt2 = 1;
		}
	}
	// cout << cnt << endl;
	ll flag = 1;
	for (int i = 1; i < cnt; ++i){
		if (vec[i][0] == 1){
			merge(vec[i][1], vec[i][2]);
		}
		else{
			ll u = vec[i][1];
			for (int v = 0; v < ve[flag].size(); ++v){
				ll j = ve[flag][v].A;
				cout << u << sep << j << endl;
				if (parent(u) == parent(j) && st[j] <= st[u] && ft[j] >= ft[u])	ans[ve[flag][v].B] = 1;
				else	ans[ve[flag][v].B] = 0;
			}
			++flag;
		}
	}
	for (int i = 0; i < cnt3; ++i){
		if (ans[i])	cout << "YES\n";
		else	cout << "NO\n";
	}
	return 0;
}
/*                 now or never                 */


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define ll long long
#define ld long double
#define endl "\n"
#define fi first
#define se second
#define y1 sadjfskldf
#define p_b push_back
#define sqr(asdf) ((asdf) * (asdf))
using namespace std;
using namespace __gnu_pbds;

const ll N = 2e5 + 200;
const ll MOD = 1e9 + 7;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll n,m,x,y,p[N],l,paket[N],col[N],sz[N],step,a,b;
vector<ll> v[N];
vector<pair<ll, pair<ll, ll> > > c;
void dfs(ll x,ll y)
{
    col[x] = ++step;
    sz[x] = 1;
    for(auto to : v[x]) if(to != y)
    {
        dfs(to, x);
        sz[x] += sz[to];
    }
}
ll get(ll v)
{
    if(p[v] == v) return v;
    return p[v] = get(p[v]);
}
int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= n; i++) p[i] = i;
    for(int i = 1; i <= m; i++)
    {
        cin>>l;
        if(l == 1)
        {
            cin>>x>>y;
            p[x] = y;
            v[y].p_b(x);
            c.p_b({l, {x, y}});
        }
        if(l == 2)
        {
            cin>>x;
            paket[++step] = x;
            c.p_b({l, {x, 0}});
        }
        if(l == 3)
        {
            cin>>x>>y;
            c.p_b({l, {x, y}});
        }
    }
    step = 0;
    dfs(1, 1);
//    for(int i = 1; i <= n; i++) if(p[i] == i) dfs(i, i);
    for(int i = 1; i <= n; i++) p[i] = i;
    for(auto q : c)
    {
        x = q.se.fi;
        y = q.se.se;
        if(q.fi == 1) p[x] = y;
        if(q.fi == 3)
        {
            y = paket[y];
            a = get(x);
            b = get(y);
            if(a == b && col[x] + sz[x] - 1 >= col[y] && col[x] <= col[y])
            {
                cout<<"YES"<<endl;
            }
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define ll long long
#define ld long double
#define endl "\n"
#define fi first
#define se second
#define y1 sadjfskldf
#define p_b push_back
#define sqr(asdf) ((asdf) * (asdf))
using namespace std;
using namespace __gnu_pbds;

const ll N = 2e5 + 200;
const ll MOD = 1e9 + 7;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll n,m,x,y,p[N],l,paket[N],col[N],sz[N],step,a,b;
vector<ll> v[N];
vector<pair<ll, pair<ll, ll> > > c;
void dfs(ll x,ll y)
{
    col[x] = ++step;
    sz[x] = 1;
    for(auto to : v[x]) if(to != y)
    {
        dfs(to, x);
        sz[x] += sz[to];
    }
}
ll get(ll v)
{
    if(p[v] == v) return v;
    return p[v] = get(p[v]);
}
int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= m; i++)
    {
        cin>>l;
        if(l == 1)
        {
            cin>>x>>y;
            p[x] = y;
            v[y].p_b(x);
            c.p_b({l, {x, y}});
        }
        if(l == 2)
        {
            cin>>x;
            paket[++step] = x;
            c.p_b({l, {x, 0}});
        }
        if(l == 3)
        {
            cin>>x>>y;
            c.p_b({l, {x, y}});
        }
    }
    step = 0;
    for(int i = 1; i <= n; i++) if(p[i] == 0) dfs(i, i);
    for(int i = 1; i <= n; i++) p[i] = i;
    for(auto q : c)
    {
        x = q.se.fi;
        y = q.se.se;
        if(q.fi == 1) p[x] = y;
        if(q.fi == 3)
        {
            y = paket[y];
            a = get(x);
            b = get(y);
//            cout<<x<<" "<<y<<" : "<<a<<" "<<b<<endl;
            if(a == b && col[x] + sz[x] > col[y] && col[x] <= col[y])
            {
                cout<<"YES"<<endl;
            }
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define ll long long
#define ld long double
#define endl "\n"
#define fi first
#define se second
#define y1 sadjfskldf
#define p_b push_back
#define sqr(asdf) ((asdf) * (asdf))
using namespace std;
using namespace __gnu_pbds;

const ll N = 2e5 + 200;
const ll MOD = 1e9 + 7;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll n,m,x,y,p[N],l,paket[N],col[N],sz[N],step,a,b;
vector<ll> v[N];
vector<pair<ll, pair<ll, ll> > > c;
void dfs(ll x,ll y)
{
    col[x] = ++step;
    sz[x] = 1;
    for(auto to : v[x]) if(to != y)
    {
        dfs(to, x);
        sz[x] += sz[to];
    }
}
ll get(ll v)
{
    if(p[v] == v) return v;
    return p[v] = get(p[v]);
}
int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= n; i++) p[i] = i;
    for(int i = 1; i <= m; i++)
    {
        cin>>l;
        if(l == 1)
        {
            cin>>x>>y;
            p[x] = y;
            v[y].p_b(x);
            c.p_b({l, {x, y}});
        }
        if(l == 2)
        {
            cin>>x;
            paket[++step] = x;
            c.p_b({l, {x, 0}});
        }
        if(l == 3)
        {
            cin>>x>>y;
            c.p_b({l, {x, y}});
        }
    }
    step = 0;
    for(int i = 1; i <= n; i++) if(p[i] == i) dfs(i, i);
    for(int i = 1; i <= n; i++) p[i] = i;
    for(auto q : c)
    {
        x = q.se.fi;
        y = q.se.se;
        if(q.fi == 1) p[x] = y;
        if(q.fi == 3)
        {
            y = paket[y];
            a = get(x);
            b = get(y);
            if(a == b && col[x] + sz[x] - 1 >= col[y] && col[x] <= col[y])
            {
                cout<<"YES"<<endl;
            }
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

#define ll long long
#define ld long double
#define endl "\n"
#define fi first
#define se second
#define y1 sadjfskldf
#define p_b push_back
#define sqr(asdf) ((asdf) * (asdf))
using namespace std;
using namespace __gnu_pbds;

const ll N = 2e5 + 200;
const ll MOD = 1e9 + 7;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll n,m,x,y,p[N],l,paket[N],col[N],sz[N],step,a,b;
vector<ll> v[N];
vector<pair<ll, ll> > ans,quest[N];
vector<pair<ll, pair<ll, ll> > > c;
void dfs(ll x,ll y)
{
    col[x] = ++step;
    sz[x] = 1;
    for(auto to : v[x]) if(to != y)
    {
        dfs(to, x);
        sz[x] += sz[to];
    }
}
ll get(ll v)
{
    if(p[v] == v) return v;
    return p[v] = get(p[v]);
}
int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i = 1; i <= m; i++)
    {
        cin>>l;
        if(l == 1)
        {
            cin>>x>>y;
            p[x] = y;
            v[y].p_b(x);
            c.p_b({l, {x, y}});
        }
        if(l == 2)
        {
            cin>>x;
            c.p_b({l, {x, 0}});
        }
        if(l == 3)
        {
            cin>>x>>y;
            quest[y].p_b({x, i});
            c.p_b({l, {x, y}});
        }
    }
    step = 0;
    for(int i = 1; i <= n; i++)
    {
        if(p[i] == 0) dfs(i, i);
        p[i] = i;
    }
    step = 0;
    for(auto q : c)
    {
        x = q.se.fi;
        y = q.se.se;
        if(q.fi == 1) p[x] = y;

        if(q.fi == 2)
        {
            a = x;
            for(auto u : quest[++step])
            {
                b = u.fi;
                ans.push_back({u.se, ((get(a) == get(b)) && (col[b] + sz[b] > col[a] && col[b] <= col[a]))});
            }
        }
    }
    sort(ans.begin(), ans.end());
    for(auto x : ans)
    {
        cout<<(x.se ? "YES" : "NO")<<endl;
    }
    return 0;
}