#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int N=200005;
int n,m;
int in[N];
int f[N],g[N];
vector<int> E[N],G[N];
bool book[N];
vector<int> topo()
{
	queue<int>q;
	for(int i=1;i<=n;i++)
		if(in[i]==0) q.push(i);
	vector<int>res;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		if(book[u]) continue;
		book[u]=true;
		res.push_back(u);
		for(int v:E[u])
		{
			in[v]--;
			if(in[v]==0) q.push(v);
		}
	}
	if(res.size()!=n)
	{
		printf("-1");
		exit(0);
	}
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		E[x].push_back(y);
		G[y].push_back(x);
		in[y]++;
	}
	vector<int> s=topo();
	for(int i=1;i<=n;i++)
		f[i]=g[i]=i;
	for(int u:s)
		for(int v:G[u]) f[u]=min(f[u],f[v]);
	for(int i=s.size()-1;i>=0;i--)
	{
		int u=s[i];
		for(int v:E[u]) g[u]=min(g[u],g[v]);
	}
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(min(f[i],g[i])==i) cnt++;
	printf("%d\n",cnt);
	for(int i=1;i<=n;i++)
		if(min(f[i],g[i])==i) printf("A");
		else printf("E");
	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=200005;
int n,m;
int in[N];
int f[N],g[N];
vector<int> E[N],G[N];
vector<int> topo()
{
	vector<int>q;
	q.clear();
	for(int i=1;i<=n;i++)
		if(in[i]==0) q.push_back(i);
	for(int i=0;i<q.size();i++)
		for(int v:E[q[i]])
		{
			in[v]--;
			if(in[v]==0) q.push_back(v);
		}
	if(q.size()!=n)
	{
		printf("-1");
		exit(0);
	}
	return q;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		E[x].push_back(y);
		G[y].push_back(x);
		in[y]++;
	}
	vector<int> s=topo();
	for(int i=1;i<=n;i++)
		f[i]=g[i]=i;
	for(int u:s)
		for(int v:G[u]) f[u]=min(f[u],f[v]);
	for(int i=s.size()-1;i>=0;i--)
	{
		int u=s[i];
		for(int v:E[u]) g[u]=min(g[u],g[v]);
	}
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(min(f[i],g[i])==i) cnt++;
	printf("%d\n",cnt);
	for(int i=1;i<=n;i++)
		if(min(f[i],g[i])==i) printf("A");
		else printf("E");
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

struct node {
    node *next;
    int where;
} *first[200001], a[200001];

int l, n, m, c[200001], v[200001], r[200001];

inline void makelist(int x, int y) {
    a[++l].where = y;
    a[l].next = first[x];
    first[x] = &a[l];
}

int main() {
    scanf("%d%d", &n, &m);
    memset(first, 0, sizeof(first)); l = 0;
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        makelist(x, y);
        ++v[y]; ++r[y];
    }
    int k = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i])
            c[++k] = i;
    for (int l = 1; l <= k; l++) {
        int m = c[l];
        for (node *x = first[m]; x; x = x->next)
            if (!--v[x->where])
                c[++k] = x->where;
    }
    if (k != n) {
        printf("-1\n");
        return 0;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
        if (!r[i])
            ++ans;
    printf("%d\n", ans);
    for (int i = 1; i <= n; i++)
        if (r[i])
            printf("E");
        else
            printf("A");
    printf("\n");
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

struct node {
    node *next;
    int where;
} *first[200001], a[200001];

int l, n, m, c[200001], v[200001], r[200001], f[200001], g[200001];

inline void makelist(int x, int y) {
    a[++l].where = y;
    a[l].next = first[x];
    first[x] = &a[l];
}

int main() {
    scanf("%d%d", &n, &m);
    memset(first, 0, sizeof(first)); l = 0;
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        makelist(x, y);
        ++v[y];
    }
    int k = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i])
            c[++k] = i;
    for (int l = 1; l <= k; l++) {
        int m = c[l];
        for (node *x = first[m]; x; x = x->next)
            if (!--v[x->where])
                c[++k] = x->where;
    }
    if (k != n) {
        printf("-1\n");
        return 0;
    }

    for (int i = 1; i <= n; i++)
        f[i] = i, g[i] = i;

    for (int i = 1; i <= n; i++) {
        int m = c[i];
        for (node *x = first[m]; x; x = x->next)
            f[x->where] = min(f[x->where], f[m]);
    }

    for (int i = n; i; i--) {
        int m = c[i];
        for (node *x = first[m]; x; x = x->next)
            g[m] = min(g[x->where], g[m]);
    }

    int ans = 0;
    for (int i = 1; i <= n; i++)
        if (min(f[i], g[i]) == i)
            ++ans;

    printf("%d\n", ans);
    for (int i = 1; i <= n; i++)
        if (min(f[i], g[i]) == i)
            printf("A");
        else
            printf("E");
    printf("\n");
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

struct node {
    node *next;
    int where;
} *first[200001], a[200001];

int l, n, m, c[200001], v[200001], r[200001];

inline void makelist(int x, int y) {
    a[++l].where = y;
    a[l].next = first[x];
    first[x] = &a[l];
}

int main() {
    scanf("%d%d", &n, &m);
    memset(first, 0, sizeof(first)); l = 0;
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        makelist(x, y);
        ++v[y];
        if (x < y)
            ++r[y];
        else
            ++r[x];
    }
    int k = 0;
    for (int i = 1; i <= n; i++)
        if (!v[i])
            c[++k] = i;
    for (int l = 1; l <= k; l++) {
        int m = c[l];
        for (node *x = first[m]; x; x = x->next)
            if (!--v[x->where])
                c[++k] = x->where;
    }
    if (k != n) {
        printf("-1\n");
        return 0;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
        if (!r[i])
            ++ans;
    printf("%d\n", ans);
    for (int i = 1; i <= n; i++)
        if (r[i])
            printf("E");
        else
            printf("A");
    printf("\n");
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
queue<int>q;bool t1[N],t2[N],c[N];
int n,m,h1[N],h2[N],num1,num2,r[N],sum,ans;
struct sty{int next,to;}e1[N];
struct stz{int next,to;}e2[N];
void add1(int from,int to){e1[++num1].next=h1[from];e1[num1].to=to;h1[from]=num1;}
void add2(int from,int to){e2[++num2].next=h2[from];e2[num2].to=to;h2[from]=num2;}
void dfsfrom(int x){
	t1[x]=1;
	for(int i=h1[x];i;i=e1[i].next)
		if(!t1[e1[i].to])
			dfsfrom(e1[i].to);
}
void dfsbehind(int x){
	t2[x]=1;
	for(int i=h2[x];i;i=e2[i].next)
		if(!t2[e2[i].to])
			dfsbehind(e2[i].to);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;scanf("%d%d",&x,&y);
		add1(x,y);add2(y,x);r[y]++;
	}for(int i=1;i<=n;i++) if(r[i]==0) q.push(i),sum++;;
	while(q.size()){
		int f=q.front();q.pop();
		for(int i=h1[f];i;i=e1[i].next){
			int u=e1[i].to;
			r[u]--;
			if(r[u]==0) sum++,q.push(u);
		}
	}if(sum!=n){cout<<"-1"<<endl;return 0;}
	for(int i=1;i<=n;i++){
		if(!t1[i] && !t2[i]) ans++,c[i]=1;
		dfsfrom(i),dfsbehind(i);
	}cout<<ans<<endl;
	for(int i=1;i<=n;i++)if(c[i])cout<<"A";else cout<<"E";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int n,m,head[maxn],nxt[maxn],to[maxn],cnt,head1[maxn],nxt1[maxn],to1[maxn],cnt1;
bool F,ans[maxn];
int rd[maxn],cd[maxn],tot,vis[maxn],T;

inline void add_edge(int x,int y){
	nxt[++cnt]=head[x],to[cnt]=y,head[x]=cnt;
}

inline void add_edge1(int x,int y){
	nxt1[++cnt1]=head1[x],to1[cnt1]=y,head1[x]=cnt1;
}

inline void Dfs(int u,int Min){
	if(vis[u]) return;
	vis[u]=1;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v>Min) ans[v]=1;
		Dfs(v,min(Min,v));
	}
}

inline void Dfs1(int u,int Min){
	if(vis[u]) return;
	vis[u]=1;
	for(int i=head1[u];i;i=nxt1[i]){
		int v=to1[i];
		if(v>Min) ans[v]=1;
		Dfs1(v,min(Min,v));
	}
}

inline bool Topo(){
	queue<int>Q;
	for(int i=1;i<=n;i++)
	if(rd[i]==0) Q.push(i);
	while(Q.size()){
		int u=Q.front(); Q.pop(); vis[u]=1;
		for(int i=head[u];i;i=nxt[i]){
			int v=to[i];
			rd[v]--;
			if(rd[v]==0) Q.push(v);
		}
	}
	for(int i=1;i<=n;i++)
	if(!vis[i]) return 1;
	return 0;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add_edge(y,x);
		add_edge1(x,y);
		rd[x]++,cd[y]++;
	}

	if(Topo()){	printf("-1\n"); return 0; }
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) if(!vis[i]) Dfs(i,i);
//	if(n==1000) {printf("f**k\n"); return 0;}
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++) if(!vis[i]) Dfs1(i,i);

	for(int i=1;i<=n;i++) if(!ans[i]) tot++;
	printf("%d\n",tot);
	for(int i=1;i<=n;i++)
	if(!ans[i]) printf("A");
	else printf("E");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
queue<int>q;bool t1[N],t2[N],c[N];
int n,m,h[N],num1,num2,r[N],sum,ans;
struct sty{int next,to;}e1[N];
struct stz{int next,to;}e2[N];
void add1(int from,int to){e1[++num1].next=h[from];e1[num1].to=to;h[from]=num1;}
void add2(int from,int to){e2[++num2].next=h[from];e2[num2].to=to;h[from]=num2;}
void dfsfrom(int x){
	t1[x]=1;
	for(int i=h[x];i;i=e1[i].next)
		if(!t1[e1[i].to])
			dfsfrom(e1[i].to);
}
void dfsbehind(int x){
	t2[x]=1;
	for(int i=h[x];i;i=e2[i].next)
		if(!t2[e2[i].to])
			dfsbehind(e2[i].to);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;scanf("%d%d",&x,&y);
		add1(x,y);add2(y,x);r[y]++;
	}for(int i=1;i<=n;i++) if(r[i]==0) q.push(i),sum++;;
	while(q.size()){
		int f=q.front();q.pop();
		for(int i=h[f];i;i=e1[i].next){
			int u=e1[i].to;
			r[u]--;
			if(r[u]==0) sum++,q.push(u);
		}
	}if(sum!=n){cout<<"-1"<<endl;return 0;}
	for(int i=1;i<=n;i++){
		if(!t1[i] && !t2[i]) ans++,c[i]=1;
		dfsfrom(i),dfsbehind(i);
	}cout<<ans<<endl;
	for(int i=1;i<=n;i++)if(c[i])cout<<"A";else cout<<"E";
	return 0;
}


#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N=200005;
queue<int> q;
int n,m,h[N],hf[N],to[N],nx[N],tof[N],nxf[N],cnt,cntf,dg[N],dgf[N],mn[N],mnf[N],ans;
bool A[N];
inline int read()
{
	int s=0;char c=getchar();
	while(!isdigit(c))  c=getchar();
	while(isdigit(c))  s=(s<<3)+(s<<1)+(c^48),c=getchar();
	return s;
}
void add(int x,int y)
{
	to[++cnt]=y;
	nx[cnt]=h[x];
	dg[y]++;
	h[x]=cnt;
}
void addf(int x,int y)
{
	tof[++cntf]=y;
	nxf[cntf]=hf[x];
	dgf[y]++;
	hf[x]=cntf;
}
int main()
{
	n=read(),m=read();
	while(m--)
	{
		int x=read(),y=read();
		add(x,y);addf(y,x);
	}
	int lft=n;
	for(R i=1;i<=n;i++)
	{
		mn[i]=mnf[i]=i;
		if(!dg[i])  lft--,q.push(i);
	}
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(R i=h[x];i;i=nx[i])
		{
			int y=to[i];
			mn[y]=min(mn[y],mn[x]);
			if(--dg[y]==0)  q.push(y),lft--;
		}
	}
	if(lft)  {printf("-1");return 0;}
	for(R i=1;i<=n;i++)
		if(!dgf[i])  q.push(i);
	while(q.size())
	{
		int x=q.front();
		q.pop();
		for(R i=hf[x];i;i=nxf[i])
		{
			int y=tof[i];
			mnf[y]=min(mnf[y],mnf[x]);
			if(--dgf[y]==0)  q.push(y);
		}
	}
	for(R i=1;i<=n;i++)
		if(min(mn[i],mnf[i])>=i)  A[i]=1,ans++;
	printf("%d\n",ans);
	for(R i=1;i<=n;i++)  printf("%c",A[i]?'A':'E');
	return 0;
}


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

//Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair(a,b)
#define x(a) a.first
#define y(a) a.second
#define b(a) a.begin()
#define e(a) a.end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;

const int N=2e5;
int n,m,d[N+7],f[N+7],b[N+7],sm,ans[N+7];
vector<int> e[N+7],g[N+7];

int Bfs(vector<int>&q){
	q.clear();
	for(int i=1;i<=n;i++)if(!d[i]) q.pb(i);
	for(int i=0;i<sz(q);i++)
		for(int to:e[q[i]])if(!--d[to]) q.pb(to);
	return sz(q)==n;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++) scanf("%d%d",&u,&v),e[u].pb(v),g[v].pb(u);
	for(int i=1;i<=n;i++) d[i]=sz(g[i]);
	vector<int> tp;
	if(!Bfs(tp)) return puts("-1"),0;
	iota(f+1,f+n+1,1),iota(b+1,b+n+1,1);
	for(int i=0;i<=sz(tp)-1;i++)
		for(int to:g[tp[i]]) f[tp[i]]=min(f[tp[i]],f[to]);
	for(int i=sz(tp)-1;i>=0;i--)
		for(int to:e[tp[i]]) b[tp[i]]=min(b[tp[i]],b[to]);
	for(int i=1;i<=n;i++)if(min(f[i],b[i])==i) sm++,ans[i]=1;
	printf("%d\n",sm);
	for(int i=1;i<=n;i++) putchar("EA"[ans[i]]);puts("");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int N=2e5+5;
int n,m,h1[N],h2[N],u,cnt,ind[N],outd[N],pre[N],succ[N],ans;
bool b[N];
queue<int> q;
struct edge{
	int v,nxt;
} e1[N],e2[N];
int main(){
	scanf("%d%d",&n,&m);
	for(register int i=1,x,y;i<=m;++i){
		scanf("%d%d",&x,&y);
		++ind[y];
		e1[i]=(edge){y,h1[x]};
		h1[x]=i;
		++outd[x];
		e2[i]=(edge){x,h2[y]};
		h2[y]=i;
	}
	for(register int i=1;i<=n;++i)
		if(!ind[i])
			q.push(i),pre[i]=i;
	while(!q.empty()){
		u=q.front();
		q.pop();
		++cnt;
		for(register int i=h1[u],v;i;i=e1[i].nxt){
			v=e1[i].v;
			if(!ind[v]) continue;
			--ind[v];
			if(!ind[v])
				q.push(v),pre[v]=min(v,pre[u]);
		}
	}
	if(cnt<n){
		printf("-1\n");
		return 0;
	}
	while(!q.empty())
	 	q.pop();
	for(register int i=1;i<=n;++i)
		if(!outd[i])
			q.push(i),succ[i]=i;
	while(!q.empty()){
		u=q.front();
		q.pop();
		for(register int i=h2[u],v;i;i=e2[i].nxt){
			v=e2[i].v;
			if(!outd[v]) continue;
			--outd[v];
			if(!outd[v])
				q.push(v),succ[v]=min(v,succ[u]);
		}
	}
	for(register int i=1;i<=n;++i)
		if(succ[i]==i&&pre[i]==i)
			++ans,b[i]=1;
	printf("%d\n",ans);
	for(register int i=1;i<=n;++i)
		if(b[i]) printf("A");
		else printf("E");
	printf("\n");
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
#define N 200005
#define M 200005
int n,m;
struct graph{
	int fir[N],nex[M],to[M],tot;
	inline void add(int u,int v){
		to[++tot]=v;
		nex[tot]=fir[u];fir[u]=tot;
	}
}G,T;
char ANS[N];
int vis[N],instack[N];
int dfs(int u){
	vis[u]=1;instack[u]=1;
	for(reg int v,i=T.fir[u];i;i=T.nex[i]){
		v=T.to[i];
		if(instack[v]) return 1;
		if(!vis[v]){
			if(dfs(v)) return 1;
		}
	}
	instack[u]=0;
	return 0;
}
int vis_[N];
void dfs_(int u){
	vis_[u]=1;
	for(reg int i=G.fir[u];i;i=G.nex[i])
		if(!vis_[G.to[i]]) dfs_(G.to[i]);
}
int main(){
	n=read();m=read();
	for(reg int x,y,i=1;i<=m;i++){
		x=read();y=read();
		T.add(x,y);G.add(y,x);
	}
	reg int ans=0;
	for(reg int i=1;i<=n;i++){
		if(!vis[i]&&!vis_[i]){
			ans++;ANS[i]='A';
		}
		else ANS[i]='E';
		if(!vis[i]) if(dfs(i)) return std::puts("-1"),0;
		if(!vis_[i]) dfs_(i);
	}
	std::printf("%d\n%s",ans,ANS+1);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
#define N 200005
#define M 200005
int n,m;
struct graph{
	int fir[N],nex[M],to[M],tot;
	inline void add(int u,int v){
		to[++tot]=v;
		nex[tot]=fir[u];fir[u]=tot;
	}
}G,T;
char ANS[N];
int vis[N],instack[N];
int dfs(int u){
	vis[u]=1;instack[u]=1;
	for(reg int v,i=T.fir[u];i;i=T.nex[i]){
		v=T.to[i];
		if(instack[v]) return 1;
		if(!vis[v]){
			if(dfs(v)) return 1;
		}
	}
	instack[u]=0;
	return 0;
}
int vis_[N];
void dfs_(int u){
	vis_[u]=1;
	for(reg int i=G.fir[u];i;i=G.nex[i])
		if(!vis_[G.to[i]]) dfs_(G.to[i]);
}
int main(){
	n=read();m=read();
	for(reg int x,y,i=1;i<=m;i++){
		x=read();y=read();
		T.add(x,y);G.add(y,x);
	}
	reg int ans=0;
	for(reg int i=1;i<=n;i++){
		if(!vis[i]&&!vis_[i]){
			if(dfs(i)) return std::puts("-1"),0;
			dfs_(i);
			ans++;ANS[i]='A';
		}
		else ANS[i]='E';
	}
	std::printf("%d\n%s",ans,ANS+1);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
#define N 400005
#define M 800005
int n,m;
int dfn[N],low[N],scc[N],dfscnt,scccnt;
int stack[N],top;
struct graph{
	int fir[N],nex[M],to[M],tot;
	inline void add(int u,int v){
		to[++tot]=v;
		nex[tot]=fir[u];fir[u]=tot;
	}
}G,T;
void tarjan(int u){
	dfn[u]=low[u]=++dfscnt;
	stack[top++]=u;
	for(reg int i=G.fir[u],v;i;i=G.nex[i]){
		v=G.to[i];
		if(!dfn[v]) tarjan(v),low[u]=std::min(low[u],low[v]);
		else if(!scc[v]) low[u]=std::min(low[u],dfn[v]);
	}
	if(low[u]==dfn[u]){
		scccnt++;
		do{
			scc[stack[--top]]=scccnt;
		}while(stack[top]^u);
	}
}
int vis[N],instack[N];
int dfs(int u){
	vis[u]=1;instack[u]=1;
	for(reg int v,i=T.fir[u];i;i=T.nex[i]){
		v=T.to[i];
		if(instack[v]) return 1;
		if(!vis[v]){
			if(dfs(v)) return 1;
		}
	}
	instack[u]=0;
	return 0;
}
int main(){
	n=read();m=read();
	for(reg int x,y,i=1;i<=m;i++){
		x=read();y=read();
		G.add(x,y+n);G.add(x+n,y+n);
//		G.add(y,x+n);G.add(y+n,x+n);
		T.add(y,x);
	}
	for(reg int i=1;i<=n;i++)if(!vis[i]){
		if(dfs(i)) return std::puts("-1"),0;
	}
	for(reg int i=1;i<=n+n;i++)if(!dfn[i]) tarjan(i);
	reg int ans=0;
	for(reg int i=1;i<=n;i++){
		if(scc[i]==scc[i+n]) return std::puts("-1"),0;
		ans+=(scc[i]<scc[i+n]);
	}
	std::printf("%d\n",ans);
	for(reg int i=1;i<=n;i++) std::putchar(scc[i]<scc[i+n]?'A':'E');
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long Ll;
typedef vector<int> VI;
typedef VI::iterator IT;
const int N=200200;
VI ins[N];
VI outs[N];
int lk[N]={0};
int ord[N];
int ort=0;
void gg(){
	puts("-1");
	exit(0);
}
int chmn[N];
int pamn[N];
char result[N]={'\0'};
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		ins[v].push_back(u);
		outs[u].push_back(v);
	}
	queue<int> q;
	for(int i=1;i<=n;i++){
		lk[i]=ins[i].size();
		if(lk[i]==0){
			q.push(i);
		}
	}
	while(!q.empty()){
		int x=q.front();
		q.pop();
		ord[++ort]=x;
		for(IT it=outs[x].begin();it!=outs[x].end();it++){
			if(--lk[*it]==0){
				q.push(*it);
			}
		}
	}
	if(ort!=n){
		gg();
	}
	for(int i=1;i<=n;i++){
		pamn[i]=i;
		for(IT it=ins[i].begin();it!=ins[i].end();it++){
			pamn[i]=min(pamn[i],pamn[*it]);
		}
	}
	for(int i=n;i>=1;i--){
		chmn[i]=i;
		for(IT it=outs[i].begin();it!=outs[i].end();it++){
			chmn[i]=min(chmn[i],chmn[*it]);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		bool w=min(pamn[i],chmn[i])==i;
		result[i]=w?'A':'E';
		if(w){
			ans++;
		}
	}
	printf("%d\n%s\n",ans,result+1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long Ll;
typedef vector<int> VI;
typedef VI::iterator IT;
const int N=200200;
VI ins[N];
VI outs[N];
int lk[N]={0};
int ord[N];
int ort=0;
void gg(){
	puts("-1");
	exit(0);
}
int chmn[N];
int pamn[N];
char result[N]={'\0'};
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		ins[v].push_back(u);
		outs[u].push_back(v);
	}
	queue<int> q;
	for(int i=1;i<=n;i++){
		lk[i]=ins[i].size();
		if(lk[i]==0){
			q.push(i);
		}
	}
	while(!q.empty()){
		int x=q.front();
		q.pop();
		ord[++ort]=x;
		for(IT it=outs[x].begin();it!=outs[x].end();it++){
			if(--lk[*it]==0){
				q.push(*it);
			}
		}
	}
	if(ort!=n){
		gg();
	}
	for(int i=1;i<=n;i++){
		int x=ord[i];
		pamn[x]=x;
		for(IT it=ins[x].begin();it!=ins[x].end();it++){
			pamn[x]=min(pamn[x],pamn[*it]);
		}
	}
	for(int i=n;i>=1;i--){
		int x=ord[i];
		chmn[x]=x;
		for(IT it=outs[x].begin();it!=outs[x].end();it++){
			chmn[x]=min(chmn[x],chmn[*it]);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		bool w=min(pamn[i],chmn[i])==i;
		result[i]=w?'A':'E';
		if(w){
			ans++;
		}
	}
	printf("%d\n%s\n",ans,result+1);
	return 0;
}


//#pragma GCC optimize(3)
#include <random>
#include <stdio.h>
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<int, int> pii;
#define fst first
#define sed second
#define psb push_back
#define Break(x) { x; break; }
#define Return(x) { x; return; }
#define Continue(x) { x; continue; }
#define lowbit(x) ((x) & -(x))
#define sqr(x) (1LL * (x) * (x))
#define sign(x) (((x) > 0) - ((x) < 0))
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
#define MEM(x, y) memset((x), (y), sizeof(x))
#define MEN(x, y, z) memset((x), (y), sizeof((x)[0]) * (z))
#define Diz(x) (lower_bound(dz.begin(), dz.end(), (x)) - dz.begin())
#define DISCRETE(x) (x).push_back(INT_MIN), (sizeof((x).back()) == 8 ? (x).back() = LLONG_MIN : 0), sort((x).begin(), (x).end()), (x).erase(unique((x).begin(), (x).end()), (x).end())
#ifdef LOCAL
#define DEBUG(...) cout << ">> " << #__VA_ARGS__ << " =", PRT(__VA_ARGS__), cout << endl;
#define DEBUGS(...) cout << ">> " << #__VA_ARGS__ << " =", PRTS(__VA_ARGS__), cout << endl;
#define DEBUGA(...) cout << ">> " << #__VA_ARGS__ << " =", PRTA(__VA_ARGS__), cout << endl;
void PRT() {} template <typename S, typename... T> void PRT(S x, T ... y){ cout << " " << x; PRT(y...); }
void PRTS() {} template <typename S> void PRTS(S x) { for (auto v : x) cout << " " << v; }
void PRTA() {} template <typename S, typename T> void PRTA(S x, T y) { while (y--) cout << " " << *x, ++x; }
#define TIME cout << "Runing time: " << clock() << "ms\n", 0
#define __int128_t long long
#define __gcd(x, y) _Gcd((x), (y))
#define __builtin_popcount(x) _BitCnt((uint)(x))
#define __builtin_popcountll(x) _BitCnt((ull)(x))
#else
#define DEBUG(...) ;
#define DEBUGS(...) ;
#define DEBUGA(...) ;
#define TIME 0
#endif

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int dir[8][2] = { -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1 };
template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; }
template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; }
template<typename S, typename T> inline void Adm(S &a, const T &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }
template<typename T> inline bool IsPri(T x) { if (x < 2) return false; for (T i = 2; i * i <= x; ++i) if (x % i == 0) return false; return true; }
template<typename T> inline T _Gcd(T a, T b){ while (b){ T t = b; b = a % b; a = t; } return a; }
template<typename T> inline int _BitCnt(T x){ int cnt = 0; while (x)++cnt, x &= x - 1; return cnt; }
inline ll Pow(ll a, ll n) { ll t = 1; a %= MOD; while (n > 0) { if (n & 1) t = t * a % MOD; a = a * a % MOD, n >>= 1; } return t % MOD; }
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
//能ll就开 ""[] vector* nm全局函数默认传参 需要多开和嵌套再开结构体 .count

const int N = 2e5 + 100;
vector<int> e[N], r[N];
char ans[N];

int vis1[N], vis2[N];
void DFS(int x, vector<int> *e, int *vis)
{
	if (vis[x] == 1)
		puts("-1"), exit(0);
	if (vis[x] == -1)
		return;
	vis[x] = 1;
	for (int y : e[x])
		DFS(y, e, vis);
	vis[x] = -1;
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
	//freopen("C:/output.txt", "w", stdout);
#endif
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; ++i)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v), r[v].push_back(u); //正反存两个图
	}
	int cnt = 0;
	for (int i = 1; i <= n; ++i) //分配是有优先级的 编号小先分配
	{
		if (vis1[i] || vis2[i]) //限制是双向的有限制就不能填A
			ans[i] = 'E';
		else //无约束分A
			ans[i] = 'A', ++cnt;
		DFS(i, e, vis1), DFS(i, r, vis2); //约束其它点
	}
	printf("%d\n%s\n", cnt, ans + 1);

	return TIME;
}


//#pragma GCC optimize(3)
#include <random>
#include <stdio.h>
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<int, int> pii;
#define fst first
#define sed second
#define psb push_back
#define Break(x) { x; break; }
#define Return(x) { x; return; }
#define Continue(x) { x; continue; }
#define lowbit(x) ((x) & -(x))
#define sqr(x) (1LL * (x) * (x))
#define sign(x) (((x) > 0) - ((x) < 0))
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
#define MEM(x, y) memset((x), (y), sizeof(x))
#define MEN(x, y, z) memset((x), (y), sizeof((x)[0]) * (z))
#define Diz(x) (lower_bound(dz.begin(), dz.end(), (x)) - dz.begin())
#define DISCRETE(x) (x).push_back(INT_MIN), (sizeof((x).back()) == 8 ? (x).back() = LLONG_MIN : 0), sort((x).begin(), (x).end()), (x).erase(unique((x).begin(), (x).end()), (x).end())
#ifdef LOCAL
#define DEBUG(...) cout << ">> " << #__VA_ARGS__ << " =", PRT(__VA_ARGS__), cout << endl;
#define DEBUGS(...) cout << ">> " << #__VA_ARGS__ << " =", PRTS(__VA_ARGS__), cout << endl;
#define DEBUGA(...) cout << ">> " << #__VA_ARGS__ << " =", PRTA(__VA_ARGS__), cout << endl;
void PRT() {} template <typename S, typename... T> void PRT(S x, T ... y){ cout << " " << x; PRT(y...); }
void PRTS() {} template <typename S> void PRTS(S x) { for (auto v : x) cout << " " << v; }
void PRTA() {} template <typename S, typename T> void PRTA(S x, T y) { while (y--) cout << " " << *x, ++x; }
#define TIME cout << "Runing time: " << clock() << "ms\n", 0
#define __int128_t long long
#define __gcd(x, y) _Gcd((x), (y))
#define __builtin_popcount(x) _BitCnt((uint)(x))
#define __builtin_popcountll(x) _BitCnt((ull)(x))
#else
#define DEBUG(...) ;
#define DEBUGS(...) ;
#define DEBUGA(...) ;
#define TIME 0
#endif

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int dir[8][2] = { -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1 };
template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; }
template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; }
template<typename S, typename T> inline void Adm(S &a, const T &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }
template<typename T> inline bool IsPri(T x) { if (x < 2) return false; for (T i = 2; i * i <= x; ++i) if (x % i == 0) return false; return true; }
template<typename T> inline T _Gcd(T a, T b){ while (b){ T t = b; b = a % b; a = t; } return a; }
template<typename T> inline int _BitCnt(T x){ int cnt = 0; while (x)++cnt, x &= x - 1; return cnt; }
inline ll Pow(ll a, ll n) { ll t = 1; a %= MOD; while (n > 0) { if (n & 1) t = t * a % MOD; a = a * a % MOD, n >>= 1; } return t % MOD; }
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
//能ll就开 ""[] vector* nm全局函数默认传参 需要多开和嵌套再开结构体 .count

const int N = 2e5 + 100;
vector<int> e[N], r[N];
char ans[N];

int vis[N];
void DFS(int x, vector<int> *e)
{
	if (vis[x] == 1)
		puts("-1"), exit(0);
	if (vis[x] == -1)
		return;
	vis[x] = 1;
	for (int y : e[x])
		DFS(y, e);
	vis[x] = -1;
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
	//freopen("C:/output.txt", "w", stdout);
#endif
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; ++i)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v), r[v].push_back(u); //正反存两个图
	}
	int cnt = 0;
	for (int i = 1; i <= n; ++i) //分配是有优先级的 编号小先分配
		if (vis[i]) //有编号小的节点约束
			ans[i] = 'E';
		else
		{
			ans[i] = 'A', ++cnt;
			DFS(i, e), DFS(i, r); //无约束分A 约束其它点
		}
	printf("%d\n%s\n", cnt, ans + 1);

	return TIME;
}


//#pragma GCC optimize(3)
#include <random>
#include <stdio.h>
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<int, int> pii;
#define fst first
#define sed second
#define psb push_back
#define Break(x) { x; break; }
#define Return(x) { x; return; }
#define Continue(x) { x; continue; }
#define lowbit(x) ((x) & -(x))
#define sqr(x) (1LL * (x) * (x))
#define sign(x) (((x) > 0) - ((x) < 0))
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
#define MEM(x, y) memset((x), (y), sizeof(x))
#define MEN(x, y, z) memset((x), (y), sizeof((x)[0]) * (z))
#define Diz(x) (lower_bound(dz.begin(), dz.end(), (x)) - dz.begin())
#define DISCRETE(x) (x).push_back(INT_MIN), (sizeof((x).back()) == 8 ? (x).back() = LLONG_MIN : 0), sort((x).begin(), (x).end()), (x).erase(unique((x).begin(), (x).end()), (x).end())
#ifdef LOCAL
#define DEBUG(...) cout << ">> " << #__VA_ARGS__ << " =", PRT(__VA_ARGS__), cout << endl;
#define DEBUGS(...) cout << ">> " << #__VA_ARGS__ << " =", PRTS(__VA_ARGS__), cout << endl;
#define DEBUGA(...) cout << ">> " << #__VA_ARGS__ << " =", PRTA(__VA_ARGS__), cout << endl;
void PRT() {} template <typename S, typename... T> void PRT(S x, T ... y){ cout << " " << x; PRT(y...); }
void PRTS() {} template <typename S> void PRTS(S x) { for (auto v : x) cout << " " << v; }
void PRTA() {} template <typename S, typename T> void PRTA(S x, T y) { while (y--) cout << " " << *x, ++x; }
#define TIME cout << "Runing time: " << clock() << "ms\n", 0
#define __int128_t long long
#define __gcd(x, y) _Gcd((x), (y))
#define __builtin_popcount(x) _BitCnt((uint)(x))
#define __builtin_popcountll(x) _BitCnt((ull)(x))
#else
#define DEBUG(...) ;
#define DEBUGS(...) ;
#define DEBUGA(...) ;
#define TIME 0
#endif

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int dir[8][2] = { -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1 };
template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; }
template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; }
template<typename S, typename T> inline void Adm(S &a, const T &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }
template<typename T> inline bool IsPri(T x) { if (x < 2) return false; for (T i = 2; i * i <= x; ++i) if (x % i == 0) return false; return true; }
template<typename T> inline T _Gcd(T a, T b){ while (b){ T t = b; b = a % b; a = t; } return a; }
template<typename T> inline int _BitCnt(T x){ int cnt = 0; while (x)++cnt, x &= x - 1; return cnt; }
inline ll Pow(ll a, ll n) { ll t = 1; a %= MOD; while (n > 0) { if (n & 1) t = t * a % MOD; a = a * a % MOD, n >>= 1; } return t % MOD; }
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
//能ll就开 ""[] vector* nm全局函数默认传参 需要多开和嵌套再开结构体 .count

const int N = 1e5 + 100;
int a[N], ans[N];

//a[x] 选k项相比k-1增长率
#define calc(x, k) (k) * (a[(x)] - sqr(k)) - ((k) - 1) * (a[(x)] - sqr((k) - 1))
int find(int x, double m) //增长率大于等于m的有多少项
{
	int l = 1, r = a[x], res = 0;
	while (l <= r)
	{
		int mid = l + r >> 1;
		if (calc(x, mid) >= m)
			res = mid, l = mid + 1;
		else
			r = mid - 1;
	}
	return res;
}
struct node
{
	int x;
	ll v; //再选一个x 增加v收益
	bool operator < (const node &o) const
	{
		return v < o.v;
	}
};
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
	//freopen("C:/output.txt", "w", stdout);
#endif
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
	double l = -1e33, r = 1e24, res = 1e24;
	while (r - l > 10)
	{
		double mid = (l + r) / 2;
		int cnt = 0;
		for (int i = 1; i <= n; ++i)
			cnt += find(i, mid);
		if (cnt <= k)
			res = mid, r = mid;
		else
			l = mid;
	}
	priority_queue<node> pq;
	for (int i = 1; i <= n; ++i)
	{
		ans[i] = find(i, res), k -= ans[i];
		if (ans[i] == a[i])
			pq.push({ i, LLONG_MIN });
		else
			pq.push({ i, calc(i, ans[i] + 1LL) });
	}
	if (n == 100000)
		cout << k << endl, exit(0);
	while (k--)
	{
		int i = pq.top().x; pq.pop();
		++ans[i];
		if (ans[i] == a[i])
			pq.push({ i, LLONG_MIN });
		else
			pq.push({ i, calc(i, ans[i] + 1LL) });
	}
	for (int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	puts("");

	return TIME;
}


//#pragma GCC optimize(3)
#include <random>
#include <stdio.h>
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef pair<int, int> pii;
#define fst first
#define sed second
#define psb push_back
#define Break(x) { x; break; }
#define Return(x) { x; return; }
#define Continue(x) { x; continue; }
#define lowbit(x) ((x) & -(x))
#define sqr(x) (1LL * (x) * (x))
#define sign(x) (((x) > 0) - ((x) < 0))
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
#define MEM(x, y) memset((x), (y), sizeof(x))
#define MEN(x, y, z) memset((x), (y), sizeof((x)[0]) * (z))
#define Diz(x) (lower_bound(dz.begin(), dz.end(), (x)) - dz.begin())
#define DISCRETE(x) (x).push_back(INT_MIN), (sizeof((x).back()) == 8 ? (x).back() = LLONG_MIN : 0), sort((x).begin(), (x).end()), (x).erase(unique((x).begin(), (x).end()), (x).end())
#ifdef LOCAL
#define DEBUG(...) cout << ">> " << #__VA_ARGS__ << " =", PRT(__VA_ARGS__), cout << endl;
#define DEBUGS(...) cout << ">> " << #__VA_ARGS__ << " =", PRTS(__VA_ARGS__), cout << endl;
#define DEBUGA(...) cout << ">> " << #__VA_ARGS__ << " =", PRTA(__VA_ARGS__), cout << endl;
void PRT() {} template <typename S, typename... T> void PRT(S x, T ... y){ cout << " " << x; PRT(y...); }
void PRTS() {} template <typename S> void PRTS(S x) { for (auto v : x) cout << " " << v; }
void PRTA() {} template <typename S, typename T> void PRTA(S x, T y) { while (y--) cout << " " << *x, ++x; }
#define TIME cout << "Runing time: " << clock() << "ms\n", 0
#define __int128_t long long
#define __gcd(x, y) _Gcd((x), (y))
#define __builtin_popcount(x) _BitCnt((uint)(x))
#define __builtin_popcountll(x) _BitCnt((ull)(x))
#else
#define DEBUG(...) ;
#define DEBUGS(...) ;
#define DEBUGA(...) ;
#define TIME 0
#endif

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int dir[8][2] = { -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1 };
template<typename S, typename T> inline bool Min(S &a, const T &b){ return a > b ? a = b, true : false; }
template<typename S, typename T> inline bool Max(S &a, const T &b){ return a < b ? a = b, true : false; }
template<typename S, typename T> inline void Adm(S &a, const T &b){ a = (a + b) % MOD; if (a < 0) a += MOD; }
template<typename T> inline bool IsPri(T x) { if (x < 2) return false; for (T i = 2; i * i <= x; ++i) if (x % i == 0) return false; return true; }
template<typename T> inline T _Gcd(T a, T b){ while (b){ T t = b; b = a % b; a = t; } return a; }
template<typename T> inline int _BitCnt(T x){ int cnt = 0; while (x)++cnt, x &= x - 1; return cnt; }
inline ll Pow(ll a, ll n) { ll t = 1; a %= MOD; while (n > 0) { if (n & 1) t = t * a % MOD; a = a * a % MOD, n >>= 1; } return t % MOD; }
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
//能ll就开 ""[] vector* nm全局函数默认传参 需要多开和嵌套再开结构体 .count

const int N = 2e5 + 100;
vector<int> e[N], r[N];
char ans[N];

int vis1[N], vis2[N];
void DFS(int x, vector<int> *e, int *vis)
{
	if (vis[x] == 1)
		puts("-1"), exit(0);
	if (vis[x] == -1)
		return;
	vis[x] = 1;
	for (int y : e[x])
		DFS(y, e, vis);
	vis[x] = -1;
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
	//freopen("C:/output.txt", "w", stdout);
#endif
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; ++i)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v), r[v].push_back(u); //正反存两个图
	}
	int cnt = 0;
	for (int i = 1; i <= n; ++i) //分配是有优先级的 编号小先分配
		if (vis1[i] || vis2[i]) //有编号小的节点约束
			ans[i] = 'E';
		else
		{
			ans[i] = 'A', ++cnt;
			DFS(i, e, vis1), DFS(i, r, vis2); //无约束分A 约束其它点
		}
	printf("%d\n%s\n", cnt, ans + 1);

	return TIME;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200005

ll n,a[N],vis[N];

int main(){
	int t;cin>>t;
	while(t--){
		cin>>n;
		for(int i=0;i<n;i++)scanf("%lld",&a[i]);
		for(int i=0;i<n;i++)
			a[i]=(a[i]%n+i+n)%n;
		for(int i=0;i<n;i++)vis[i]=0;
		for(int i=0;i<n;i++)vis[a[i]]=1;
		int f=0;
		for(int i=0;i<n;i++)if(!vis[i]){
			f=1;
		}
		if(!f)puts("YES");
		else puts("NO");
	}
}


/*
u<v，那么u->v连边，形成一个DAG
如果u选择的是全称量词，那么所有u出发可达的点v，显然有u<v，所以v必须是存在量词
					   所有可以到达u的点v，显然有u>v,所以v必须是存在量词
从1开始依次扫描下去，如果没确定是存在量词，那么就可以判定为全称量词
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005

int n,m,in[N],ans[N],vis1[N],vis2[N];
vector<int>G1[N],G2[N];

void dfs1(int u){
	vis1[u]=1;
	for(auto v:G1[u])
		if(!vis1[v])dfs1(v);
}
void dfs2(int u){
	vis2[u]=1;
	for(auto v:G2[u])
		if(!vis2[v])dfs2(v);
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		in[v]++;
		G1[u].push_back(v);
		G2[v].push_back(u);
	}

	queue<int>q;
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(in[i]==0)q.push(i);
	while(q.size()){
		cnt++;
		int u=q.front();q.pop();
		for(auto v:G1[u]){
			in[v]--;
			if(in[v]==0)
				q.push(v);
		}
	}
	if(cnt!=n){puts("-1");return 0;}

	cnt=0;
	for(int i=1;i<=n;i++){
		if(!vis1[i] && !vis2[i]){
			cnt++;ans[i]=1;
		}
		if(!vis1[i])dfs1(i);
		if(!vis2[i])dfs2(i);
	}

	cout<<cnt<<'\n';
	for(int i=1;i<=n;i++)
		if(ans[i])cout<<"A";
		else cout<<"E";
}


/*
u<v，那么u->v连边，形成一个DAG
如果u选择的是全称量词，那么所有u出发可达的点v，显然有u<v，所以v必须是存在量词
					   所有可以到达u的点v，显然有u>v,所以v必须是存在量词
从1开始依次扫描下去，如果没确定是存在量词，那么就可以判定为全称量词
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005

int n,m,in[N],ans[N],vis[N];
vector<int>G1[N],G2[N];

void dfs1(int u){
	vis[u]=1;
	for(auto v:G1[u])
		if(!vis[v])dfs1(v);
}
void dfs2(int u){
	vis[u]=1;
	for(auto v:G2[u])
		if(!vis[v])dfs2(v);
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		in[v]++;
		G1[u].push_back(v);
		G2[v].push_back(u);
	}

	queue<int>q;
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(in[i]==0)q.push(i);
	while(q.size()){
		cnt++;
		int u=q.front();q.pop();
		for(auto v:G1[u]){
			in[v]--;
			if(in[v]==0)
				q.push(v);
		}
	}
	if(cnt!=n){puts("-1");return 0;}

	cnt=0;
	for(int i=1;i<=n;i++)
		if(!vis[i]){
			cnt++;ans[i]=1;
			dfs1(i);
			dfs2(i);
		}

	cout<<cnt<<'\n';
	for(int i=1;i<=n;i++)
		if(ans[i])cout<<"A";
		else cout<<"E";
}


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

int n,m,in[N],ans[N],out[N];
vector<int>G[N];

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;scanf("%d%d",&u,&v);
		G[v].push_back(u);//u<v
		in[u]++;out[v]++;
	}
	queue<int>q;
	int tot=0;
	for(int i=1;i<=n;i++){
		if(out[i]==0)ans[i]=1,tot++;
		if(in[i]==0)q.push(i);
	}

	while(q.size()){
		int u=q.front();q.pop();
		for(auto v:G[u]){
			in[v]--;
			if(in[v]==0)
				q.push(v);
		}
	}

	for(int i=1;i<=n;i++)
		if(in[i]){
			puts("-1");
			return 0;
		}

	cout<<tot<<'\n';
	for(int i=1;i<=n;i++)
		if(ans[i])cout<<"A";
		else cout<<"E";
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Qza{

	#define MAXN 200005
	#define MAXM 200005

	typedef long long ll;

	int col[MAXN],vis[MAXN];
	int en[MAXN],nex[MAXM],to[MAXM];
	int en1[MAXN],nex1[MAXM],to1[MAXM];

	int dfs(int x,int c)
	{
		vis[x]=c;
		for(int p=en[x];p;p=nex[p]) {
			if(vis[to[p]]!=c) {
				if(dfs(to[p],c)) return 1;
			}
			else return 1;
		}
		return 0;
	}

	void dfs1(int x,int c)
	{
		for(int p=en1[x];p;p=nex1[p]) {
			if(!col[to1[p]]) {
				col[to1[p]]=c;
				dfs1(to1[p],c);
			}
		}
	}
	void dfs2(int x,int c)
	{
		for(int p=en[x];p;p=nex[p]) {
			if(!col[to[p]]) {
				col[to[p]]=c;
				dfs2(to[p],c);
			}
		}
	}

	void add_edge(int x,int y)
	{
		static int cnt=0;
		nex[++cnt]=en[x]; to[cnt]=y; en[x]=cnt;
		nex1[cnt]=en1[y]; to1[cnt]=x; en1[y]=cnt;
	}

	void main()
	{
		int n,m,c=0,a,b,ans=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=m;++i) {
			scanf("%d %d",&a,&b);
			add_edge(b,a);
		}
		for(int i=1;i<=n;++i) {
			if(!vis[i]) {
				++c;
				if(dfs(i,c)) {
					printf("-1");
					return ;
				}
			}
		}
		for(int i=1;i<=n;++i) {
			if(!col[i]) {
				++ans; col[i]=1;
				dfs1(i,2);
				dfs2(i,2);
			}
		}
		for(int i=1;i<=n;++i) {
			if(col[i]==1) printf("A");
			else printf("E");
		}
	}
}
int main()
{
	Qza::main();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Qza{

	#define MAXN 200005
	#define MAXM 200005

	typedef long long ll;

	int col[MAXN],vis[MAXN];
	int en[MAXN],nex[MAXM],to[MAXM];
	int en1[MAXN],nex1[MAXM],to1[MAXM];

	int dfs(int x,int c)
	{
		vis[x]=c;
		for(int p=en[x];p;p=nex[p]) {
			if(vis[to[p]]!=c) {
				if(dfs(to[p],c)) return 1;
			}
			else return 1;
		}
		return 0;
	}

	void dfs1(int x,int c)
	{
		for(int p=en1[x];p;p=nex1[p]) {
			if(!col[to1[p]]) {
				col[to1[p]]=c;
				dfs1(to1[p],c);
			}
		}
	}
	void dfs2(int x,int c)
	{
		for(int p=en[x];p;p=nex[p]) {
			if(!col[to[p]]) {
				col[to[p]]=c;
				dfs2(to[p],c);
			}
		}
	}

	void add_edge(int x,int y)
	{
		static int cnt=0;
		nex[++cnt]=en[x]; to[cnt]=y; en[x]=cnt;
		nex1[cnt]=en1[y]; to1[cnt]=x; en1[y]=cnt;
	}

	void main()
	{
		int n,m,c=0,a,b,ans=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=m;++i) {
			scanf("%d %d",&a,&b);
			add_edge(b,a);
		}
		for(int i=1;i<=n;++i) {
			if(!vis[i]) {
				++c;
				if(dfs(i,c)) {
					printf("-1");
					return ;
				}
			}
		}
		for(int i=1;i<=n;++i) {
			if(!col[i]) {
				++ans; col[i]=1;
				dfs1(i,2);
				dfs2(i,2);
			}
		}
		printf("%d\n",ans);	/* 格式错了见祖宗。。。 */
		for(int i=1;i<=n;++i) {
			if(col[i]==1) printf("A");
			else printf("E");
		}
	}
}
int main()
{
	Qza::main();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Qza{

	#define MAXN 200005
	#define MAXM 200005

	typedef long long ll;

	int col[MAXN],vis[MAXN],col1[MAXN],col2[MAXN];
	int en[MAXN],nex[MAXM],to[MAXM];
	int en1[MAXN],nex1[MAXM],to1[MAXM];

	int dfs(int x,int c)
	{
		vis[x]=c;
		for(int p=en[x];p;p=nex[p]) {
			if(vis[to[p]]!=c) {
				if(dfs(to[p],c)) return 1;
			}
			else return 1;
		}
		return 0;
	}

	void dfs1(int x,int c)
	{
		for(int p=en1[x];p;p=nex1[p]) {
			if(!col1[to1[p]]) {
				col1[to1[p]]=c;
				dfs1(to1[p],c);
			}
		}
	}
	void dfs2(int x,int c)
	{
		for(int p=en[x];p;p=nex[p]) {
			if(!col2[to[p]]) {
				col2[to[p]]=c;
				dfs2(to[p],c);
			}
		}
	}

	void add_edge(int x,int y)
	{
		static int cnt=0;
		nex[++cnt]=en[x]; to[cnt]=y; en[x]=cnt;
		nex1[cnt]=en1[y]; to1[cnt]=x; en1[y]=cnt;
	}

	void main()
	{
		int n,m,c=0,a,b,ans=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=m;++i) {
			scanf("%d %d",&a,&b);
			add_edge(b,a);
		}
		for(int i=1;i<=n;++i) {
			if(!vis[i]) {
				++c;
				if(dfs(i,c)) {
					printf("-1");
					return ;
				}
			}
		}
		for(int i=1;i<=n;++i) {
			if(!col[i] && !col1[i] && !col2[i]) {
				++ans; col[i]=1;
			}
			dfs1(i,2);
			dfs2(i,3);
		}
		printf("%d\n",ans);	/* 格式错了见祖宗。。。 */
		for(int i=1;i<=n;++i) {
			if(col[i]==1) printf("A");
			else printf("E");
		}
	}
}
int main()
{
	Qza::main();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Qza{

	#define MAXN 200005
	#define MAXM 200005

	typedef long long ll;

	int col[MAXN],in[MAXN],q[MAXN],col1[MAXN],col2[MAXN];
	int en[MAXN],nex[MAXM],to[MAXM];
	int en1[MAXN],nex1[MAXM],to1[MAXM];

	/* 假的判环。 */
	/*int dfs(int x,int c)
	{
		vis[x]=c;
		for(int p=en[x];p;p=nex[p]) {
			if(vis[to[p]]!=c) {
				if(dfs(to[p],c)) return 1;
			}
			else return 1;
		}
		return 0;
	}*/
	int top_sort(int n)
	{
		int t=0;
		for(int i=1;i<=n;++i) {
			if(!in[i]) q[++t]=i;
		}
		for(int i=1;i<=t;++i) {
			for(int p=en[q[i]];p;p=nex[p]) {
				--in[to[p]];
				if(!in[to[p]]) q[++t]=to[p];
			}
		}
		return t!=n;
	}

	void dfs1(int x,int c)
	{
		for(int p=en1[x];p;p=nex1[p]) {
			if(!col1[to1[p]]) {
				col1[to1[p]]=c;
				dfs1(to1[p],c);
			}
		}
	}
	void dfs2(int x,int c)
	{
		for(int p=en[x];p;p=nex[p]) {
			if(!col2[to[p]]) {
				col2[to[p]]=c;
				dfs2(to[p],c);
			}
		}
	}

	void add_edge(int x,int y)
	{
		static int cnt=0;
		nex[++cnt]=en[x]; to[cnt]=y; en[x]=cnt;
		nex1[cnt]=en1[y]; to1[cnt]=x; en1[y]=cnt;
	}

	void main()
	{
		int n,m,a,b,ans=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=m;++i) {
			scanf("%d %d",&a,&b);
			add_edge(b,a);
			++in[a];
		}
		if(top_sort(n)) {
			printf("-1");
			return ;
		}
		/*for(int i=1;i<=n;++i) {
			if(!vis[i]) {
				++c;
				if(dfs(i,c)) {
					printf("-1");
					return ;
				}
			}
		}*/
		for(int i=1;i<=n;++i) {
			if(!col[i] && !col1[i] && !col2[i]) {
				++ans; col[i]=1;
			}
			dfs1(i,2);
			dfs2(i,3);
		}
		printf("%d\n",ans);	/* 格式错了见祖宗。。。 */
		for(int i=1;i<=n;++i) {
			if(col[i]==1) printf("A");
			else printf("E");
		}
	}
}
int main()
{
	Qza::main();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace Qza{

	#define MAXN 200005
	#define MAXM 200005

	typedef long long ll;

	int col[MAXN],vis[MAXN];
	int en[MAXN],nex[MAXM],to[MAXM];
	int en1[MAXN],nex1[MAXM],to1[MAXM];

	int dfs(int x,int c)
	{
		vis[x]=c;
		for(int p=en[x];p;p=nex[p]) {
			if(vis[to[p]]!=c) {
				if(dfs(to[p],c)) return 1;
			}
			else return 1;
		}
		return 0;
	}

	void dfs1(int x,int c)
	{
		for(int p=en1[x];p;p=nex1[p]) {
			if(!col[to1[p]]) {
				col[to1[p]]=c;
				dfs1(to1[p],c);
			}
		}
	}
	void dfs2(int x,int c)
	{
		for(int p=en[x];p;p=nex[p]) {
			if(!col[to[p]]) {
				col[to[p]]=c;
				dfs2(to[p],c);
			}
		}
	}

	void add_edge(int x,int y)
	{
		static int cnt=0;
		nex[++cnt]=en[x]; to[cnt]=y; en[x]=cnt;
		nex1[cnt]=en1[y]; to1[cnt]=x; en1[y]=cnt;
	}

	void main()
	{
		int n,m,c=0,a,b,ans=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=m;++i) {
			scanf("%d %d",&a,&b);
			add_edge(b,a);
		}
		for(int i=1;i<=n;++i) {
			if(!vis[i]) {
				++c;
				if(dfs(i,c)) {
					printf("-1");
					return ;
				}
			}
		}
		for(int i=1;i<=n;++i) {
			if(!col[i]) {
				++ans; col[i]=1;
			}
			dfs1(i,2);
			dfs2(i,2);
		}
		printf("%d\n",ans);	/* 格式错了见祖宗。。。 */
		for(int i=1;i<=n;++i) {
			if(col[i]==1) printf("A");
			else printf("E");
		}
	}
}
int main()
{
	Qza::main();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
struct edge
{
	int to,nxt;
}e[N];
int head[N],cnt=0;
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int siz[N];
bool vis[N];
int q[N],h=1,t=0;
bool check(int n)
{
	for (int i=1;i<=n;i++)
	if (siz[i]==0)
	q[++t]=i;
	while (h<=t)
	{
		int now=q[h];
		for (int i=head[now];i;i=e[i].nxt)
		{
			int to=e[i].to;
			siz[to]--;
			if (!siz[to]) q[++t]=to;
		}
		h++;
	}
	return t!=n;
}

signed main()
{
	memset(vis,0,sizeof(vis));
	memset(siz,0,sizeof(siz));
	int n=read(),m=read(),ans=n;
	for (int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v);
		siz[v]++;
		vis[v]=1;
		if (v<u) vis[u]=1;
	}
	if (check(n)) return puts("-1"),0;
	for (int i=1;i<=n;i++) ans-=vis[i];
	print(ans);
	for (int i=1;i<=n;i++) putchar(vis[i]?'E':'A');

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
struct edge
{
	int to,nxt;
}e[N];
int head[N],cnt=0;
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int siz[N];
bool vis[N];
int q[N],h=1,t=0;
bool check(int n)
{
	for (int i=1;i<=n;i++)
	if (siz[i]==0)
	q[++t]=i;
	while (h<=t)
	{
		int now=q[h];
		for (int i=head[now];i;i=e[i].nxt)
		{
			int to=e[i].to;
			siz[to]--;
			if (!siz[to]) q[++t]=to;
		}
		h++;
	}
	return t!=n;
}

signed main()
{
	memset(vis,0,sizeof(vis));
	memset(siz,0,sizeof(siz));
	int n=read(),m=read(),ans=n;
	for (int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v);
		siz[v]++;
		vis[max(u,v)]=1;
	}
	if (check(n)) return puts("-1"),0;
	for (int i=1;i<=n;i++) ans-=vis[i];
	print(ans);
	for (int i=1;i<=n;i++) putchar(vis[i]?'E':'A');

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
struct edge
{
	int to,nxt;
}e[N];
int head[N],cnt=0;
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int siz[N];
bool vis[N];
int q[N],h=1,t=0;
bool check(int n)
{
	for (int i=1;i<=n;i++)
	if (siz[i]==0)
	q[++t]=i;
	while (h<=t)
	{
		int now=q[h];
		for (int i=head[now];i;i=e[i].nxt)
		{
			int to=e[i].to;
			siz[to]--;
			if (!siz[to]) q[++t]=now;
		}
		h++;
	}
	return t!=n;
}

signed main()
{
	memset(vis,0,sizeof(vis));
	memset(siz,0,sizeof(siz));
	int n=read(),m=read(),ans=n;
	for (int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v);
		siz[v]++;
		vis[max(u,v)]=1;
	}
	if (check(n)) return puts("-1"),0;
	for (int i=1;i<=n;i++) ans-=vis[i];
	print(ans);
	for (int i=1;i<=n;i++) putchar(vis[i]?'E':'A');

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
struct edge
{
	int to,nxt;
}e[N];
int head[N],cnt=0;
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int siz[N];
bool vis[N];
int q[N],h=1,t=0;
bool check(int n)
{
	for (int i=1;i<=n;i++)
	if (siz[i]==0)
	q[++t]=i;
	while (h<=t)
	{
		int now=q[h];
		for (int i=head[now];i;i=e[i].nxt)
		{
			int to=e[i].to;
			siz[to]--;
			if (!siz[to]) q[++t]=to;
		}
		h++;
	}
	return t!=n;
}

signed main()
{
	memset(vis,0,sizeof(vis));
	memset(siz,0,sizeof(siz));
	int n=read(),m=read(),ans=n;
	for (int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v);
		siz[v]++;
		vis[v]=1;
	}
	if (check(n)) return puts("-1"),0;
	for (int i=1;i<=n;i++) ans-=vis[i];
	print(ans);
	for (int i=1;i<=n;i++) putchar(vis[i]?'E':'A');

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
struct edge
{
	int to,nxt;
}e[N];
int head[N],cnt=0;
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int siz[N],Min1[N],Min2[N];
bool vis[N];
int q[N],h=1,t=0;
bool check(int n)
{
	for (int i=1;i<=n;i++)
	if (siz[i]==0)
	q[++t]=i;
	while (h<=t)
	{
		int now=q[h];
		for (int i=head[now];i;i=e[i].nxt)
		{
			int to=e[i].to;
			siz[to]--;
			if (!siz[to]) q[++t]=to;
		}
		h++;
	}
	return t!=n;
}
vector<int>in[N],out[N];

signed main()
{
	memset(vis,0,sizeof(vis));
	memset(siz,0,sizeof(siz));
	int n=read(),m=read(),ans=0;
	for (int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v);
		siz[v]++;
		vis[max(u,v)]=1;
		in[v].push_back(u);
		out[u].push_back(v);
	}
	if (check(n)) return puts("-1"),0;
	for (int i=1;i<=n;i++) Min1[i]=Min2[i]=i;
	for (int i=1;i<=n;i++)
	{
		int now=q[i];
		for (int j=0;j<in[now].size();j++)
		Min1[now]=min(Min1[now],Min1[in[now][j]]);
	}
	for (int i=n;i>=1;i--)
	{
		int now=q[i];
		for (int j=0;j<out[now].size();j++)
		Min2[now]=min(Min2[now],Min2[out[now][j]]);
	}
	for (int i=1;i<=n;i++) vis[i]=Min1[i]>=i&&Min2[i]>=i;
	for (int i=1;i<=n;i++) ans+=vis[i];
	print(ans);
	for (int i=1;i<=n;i++) putchar(vis[i]?'A':'E');

	return 0;
}


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

const int MAXN = 2e5+5;
int min_reach[MAXN][2];
bool vst[MAXN];

void dfs(int cur, vector<vector<int> > &adj, int x) {
    vst[cur] = true;
    for (int next : adj[cur]) {
        if (!vst[next])
            dfs(next, adj, x);
        min_reach[cur][x] = min(min_reach[cur][x],min(min_reach[next][x], next));
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int N, M; cin >> N >> M;
    vector<vector<int> > adj(N);
    vector<vector<int> > adj2(N);
    vector<int> indeg(N);
    for (int i = 0; i < M; ++i) {
        int x, y; cin >> x >> y;
        --x; --y;
        adj[x].push_back(y);
        ++indeg[y];
        adj2[y].push_back(x);
    }
    stack<int> st;
    for (int i = 0; i < N; ++i) {
        if (indeg[i])
            continue;
        st.push(i);
    }
    int edge_proc = 0;
    vector<int> topo;
    while(!st.empty()) {
        int cur = st.top();
        topo.push_back(cur);
        st.pop();
        for (auto next : adj[cur]) {
            --indeg[next];
            ++edge_proc;
            if (indeg[next] == 0)
                st.push(next);
        }
    }
    if (edge_proc < M) {
        cout << -1;
        return 0;
    }
    for (int i = 0; i < N; ++i)
        min_reach[i][0] = min_reach[i][1] = INT_MAX;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj, 0);
    }
    adj = adj2;
    for (int i = 0; i < N; ++i)
        vst[i] = false;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj, 1);
    }
    int univ = 0;
    string res = "";
    for (int i = 0; i < N; ++i) {
        if (min(min_reach[i][0], min_reach[i][1]) >= i) {
            res += 'A';
            ++univ;
        }
        else
            res += 'E';
    }
    cout << univ << "\n" << res;
}


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

const int MAXN = 2e5+5;
int min_reach[MAXN];
bool vst[MAXN];

void dfs(int cur, vector<vector<int> > &adj) {
    vst[cur] = true;
    for (int next : adj[cur]) {
        if (!vst[next])
            dfs(next, adj);
        min_reach[cur] = min(min_reach[cur],min(min_reach[next], next));
    }
}

int main() {
	int N, M; cin >> N >> M;
    vector<vector<int> > adj(N);
    vector<vector<int> > adj2(N);
    vector<int> indeg(N);
    for (int i = 0; i < M; ++i) {
        int x, y; cin >> x >> y;
        --x; --y;
        adj[x].push_back(y);
        ++indeg[y];
        adj2[y].push_back(x);
    }
    stack<int> st;
    for (int i = 0; i < N; ++i) {
        if (indeg[i])
            continue;
        st.push(i);
    }
    int edge_proc = 0;
    vector<int> topo;
    while(!st.empty()) {
        int cur = st.top();
        topo.push_back(cur);
        st.pop();
        for (auto next : adj[cur]) {
            --indeg[next];
            ++edge_proc;
            if (indeg[next] == 0)
                st.push(next);
        }
    }
    if (edge_proc < M) {
        cout << -1;
        return 0;
    }
    for (int i = 0; i < N; ++i)
        min_reach[i] = INT_MAX;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj);
    }
    adj = adj2;
    for (int i = 0; i < N; ++i)
        vst[i] = false;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj);
    }
    int univ = 0;
    string res = "";
    for (int i = 0; i < N; ++i) {
        if (min_reach[i] > i) {
            res += 'A';
            ++univ;
        }
        else
            res += 'E';
    }
    cout << univ << "\n" << res;
}


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

const int MAXN = 2e5+5;
int min_reach[MAXN][2];
bool vst[MAXN];

void dfs(int cur, vector<vector<int> > &adj, int x) {
    vst[cur] = true;
    for (int next : adj[cur]) {
        if (!vst[next])
            dfs(next, adj, x);
        min_reach[cur][x] = min(min_reach[cur][x],min(min_reach[next][x], next));
    }
}

int main() {
	int N, M; cin >> N >> M;
    vector<vector<int> > adj(N);
    vector<vector<int> > adj2(N);
    vector<int> indeg(N);
    for (int i = 0; i < M; ++i) {
        int x, y; cin >> x >> y;
        --x; --y;
        adj[x].push_back(y);
        ++indeg[y];
        adj2[y].push_back(x);
    }
    stack<int> st;
    for (int i = 0; i < N; ++i) {
        if (indeg[i])
            continue;
        st.push(i);
    }
    int edge_proc = 0;
    vector<int> topo;
    while(!st.empty()) {
        int cur = st.top();
        topo.push_back(cur);
        st.pop();
        for (auto next : adj[cur]) {
            --indeg[next];
            ++edge_proc;
            if (indeg[next] == 0)
                st.push(next);
        }
    }
    if (edge_proc < M) {
        cout << -1;
        return 0;
    }
    for (int i = 0; i < N; ++i)
        min_reach[i][0] = min_reach[i][1] = INT_MAX;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj, 0);
    }
    adj = adj2;
    for (int i = 0; i < N; ++i)
        vst[i] = false;
    for (int i = 0; i < N; ++i) {
        if (!vst[i])
            dfs(i, adj, 1);
    }
    int univ = 0;
    string res = "";
    for (int i = 0; i < N; ++i) {
        if (min(min_reach[i][0], min_reach[i][1]) >= i) {
            res += 'A';
            ++univ;
        }
        else
            res += 'E';
    }
    cout << univ << "\n" << res;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define Fast_IO ios::sync_with_stdio(false);
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
//mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define fir first
#define sec second
#define mod 998244353
#define ll long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
inline int read()
{
	char ch=getchar(); int nega=1; while(!isdigit(ch)) {if(ch=='-') nega=-1; ch=getchar();}
	int ans=0; while(isdigit(ch)) {ans=ans*10+ch-48;ch=getchar();}
	if(nega==-1) return -ans;
	return ans;
}
typedef pair<int,int> pii;
inline int min(int x,int y,int z){return min(x,min(y,z));}
inline int max(int x,int y,int z){return max(x,max(y,z));}
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int add(int x,int y,int z){return add(add(x,y),z);}
inline int sub(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return 1LL*x*y%mod;}
inline int mul(int x,int y,int z){return mul(mul(x,y),z);}
#define N 200005
vector<int> G[N],H[N];
int a[N],b[N];
char res[N];
bool dfs1(int u)
{
	a[u]=1;
	for(int v:G[u])
	{
		if(a[v]==1) return 0;
		if(!a[v])
		{
			if(!dfs1(v)) return 0;
		}
	}
	a[u]=2;
	return 1;
}
bool dfs2(int u)
{
	b[u]=1;
	for(int v:H[u])
	{
		if(b[v]==1) return 0;
		if(!b[v])
		{
			if(!dfs2(v)) return 0;
		}
	}
	b[u]=2;
	return 1;
}
signed main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		G[u].pb(v),H[v].pb(u);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(!a[i]&&!b[i]) ans++,res[i]='A';
		else res[i]='E';
		if(!dfs1(i)||!dfs2(i)) {cout<<"-1\n"; return 0;}
	}
	cout<<ans<<endl;
	printf("%s",res+1);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int N=200005;
int n,m;
int in[N];
int f[N],g[N];
vector<int> E[N],G[N];
bool book[N];
vector<int> topo(){
	queue<int>q;
	for(int i=1;i<=n;i++)
	if(in[i]==0) q.push(i);
	vector<int>res;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		if(book[u]) continue;
		book[u]=true;
		res.push_back(u);
		for(int v:E[u]){
			in[v]--;
			if(in[v]==0) q.push(v);
		}
	}
	if(res.size()!=n){
		printf("-1");
		exit(0);
	}
	return res;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		E[x].push_back(y);
		G[y].push_back(x);
		in[y]++;
	}
	vector<int> s=topo();
	for(int i=1;i<=n;i++) f[i]=g[i]=i;
	for(int u:s)
	for(int v:G[u]) f[u]=min(f[u],f[v]);
	for(int i=s.size()-1;i>=0;i--){
		int u=s[i];
		for(int v:E[u]) g[u]=min(g[u],g[v]);
	}
	int cnt=0;
	for(int i=1;i<=n;i++)
	if(min(f[i],g[i])==i) cnt++;
	printf("%d\n",cnt);
	for(int i=1;i<=n;i++)
	if(min(f[i],g[i])==i) printf("A");
	else printf("E");
	return 0;
}


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

#define cs const
#define mp make_pair
#define int long long
#define mid ((l + r) >> 1)
#define cn(x) memset(x, 0, sizeof(x))
#define rep(i, x, y) for(int i = x; i <= y; ++ i)
#define sep(i, x, y) for(int i = x; i >= y; -- i)
#define fore(i, x) for(int i = fir[x]; i; i = nex[i])

cs int ff = 1e6 + 15;
cs int M = 1e9 + 7;
cs int inf = 1e18 + 1;

int fir[ff], nex[ff], to[ff], tot;
map<pair<int, int>, int> hh;
void add(int x, int y)
{
	if(hh[make_pair(x, y)]) return;
	if(x == y) return;
	hh[make_pair(x, y)] = 1;
	nex[++tot] = fir[x];
	fir[x] = tot;
	to[tot] = y;
}

vector <int> edge[ff];
void add2(int x, int y) { edge[x].push_back(y); }

cs int N = 1e6 + 15;
int stk[N], top, vis[N], dfn[N], low[N], cnt, id[N], idx, rd[N], tag;
int visa[N], visa2[N];
vector <int> rev[N];
void tar(int now)
{
	stk[++top] = now;
	vis[now] = 1;
	dfn[now] = ++cnt;
	low[now] = cnt;
	for(int i = fir[now]; i; i = nex[i])
		if(!dfn[to[i]]) tar(to[i]), low[now] = min(low[now], low[to[i]]);
		else if(vis[to[i]]) low[now] = min(low[now], dfn[to[i]]);
	if(dfn[now] == low[now])
	{
		int u = stk[top];
		++ idx;
		while(u != now)
		{
			vis[u] = 0;
			id[u] = idx;
			rev[idx].push_back(u);
			stk[top] = 0;
			-- top;
			u = stk[top];
			tag = 1;
		}
		vis[u] = 0;
		id[u] = idx;
		rev[idx].push_back(u);
		stk[top] = 0;
		-- top;
	}
}
int typ[ff];
int n, m, u[ff], v[ff];
void init()
{
	cin >> n >> m;
	rep(i, 1, m)
	{
		scanf("%lld %lld", &u[i], &v[i]);
		add(u[i], v[i]);
	}
	rep(i, 1, n)
		if(!vis[i]) tar(i);
	if(tag) { cout << "-1"; return; }
	rep(i, 1, m) add2(v[i], u[i]);
	int sss = 0;
	rep(i, 1, n)
	{
	//	if(visa[i]) continue;
		queue <int> q; q.push(i);
		if(!visa[i] && !visa2[i]) ++ sss, typ[i] = 1;
		while(!q.empty())
		{
			int u = q.front(); q.pop();
		//	cout << u << " ";
			if(visa[u]) continue;
			visa[u] = 1;
			fore(i, u)
				if(!visa[to[i]])
					q.push(to[i]);
		}
	//	cout << "\n";
		queue <int> q2; q2.push(i);
		while(!q2.empty())
		{
			int u = q2.front(); q2.pop();
		//	cout << u << " ";
			if(visa2[u]) continue;
			visa2[u] = 1;
			int sz = edge[u].size();
			for(int i = 0; i < sz; ++ i)
				if(!visa2[edge[u][i]])
					q2.push(edge[u][i]);
		}
	//	cout << "\n";

	}
	cout << sss << "\n";
	rep(i, 1, n)
		if(typ[i] == 1) cout << "A";
		else cout << "E";
}

signed main()
{
//	freopen("math.in", "r", stdin);
//	freopen("math.out", "w", stdout);
	int Ts = 1;
	rep(i, 1, Ts)
		init();
}
/*
6 4
1 2
1 3
4 5
4 6

5 6
2 1
1 3
2 3
5 3
2 5
4 5

5 5
1 4
4 3
5 4
2 3
1 5
*/


#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int n,m,head[maxn],nxt[maxn],to[maxn],cnt,head1[maxn],nxt1[maxn],to1[maxn],cnt1;
bool F,ans[maxn];
int rd[maxn],cd[maxn],tot,vis[maxn],T;

inline void add_edge(int x,int y){
	nxt[++cnt]=head[x],to[cnt]=y,head[x]=cnt;
}

inline void add_edge1(int x,int y){
	nxt1[++cnt1]=head1[x],to1[cnt1]=y,head1[x]=cnt1;
}

inline void Dfs(int u,int Min){
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v>Min) ans[v]=1;
		Dfs(v,min(Min,v));
	}
}

inline void Dfs1(int u,int Min){
	for(int i=head1[u];i;i=nxt1[i]){
		int v=to1[i];
		if(v>Min) ans[v]=1;
		Dfs1(v,min(Min,v));
	}
}

inline void dfs(int x){
	if(vis[x]==T) F=1; vis[x]=T;
	if(F) return ;
	for(int i=head[x];i;i=nxt[i])
		dfs(to[i]);
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add_edge(y,x);
		add_edge1(x,y);
		rd[x]++,cd[y]++;
	}

	for(int i=1;i<=n;i++)
	if(rd[i]==0&&cd[i]!=0) T++,dfs(i);
	if(F||T==0){printf("-1\n"); return 0;}

	for(int i=1;i<=n;i++) Dfs(i,i);
	for(int i=1;i<=n;i++) Dfs1(i,i);

	for(int i=1;i<=n;i++) if(!ans[i]) tot++;
	printf("%d\n",tot);
	for(int i=1;i<=n;i++)
	if(!ans[i]) printf("A");
	else printf("E");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

const int MN = 2e5 + 10;
std::vector<int> a[MN], b[MN];
int N, M, ans;
bool u[MN], v[MN], c[MN];
char s[MN];
bool dfs(int n)
{
	u[n]=v[n]=1;
	for(int x : a[n])
	{
		if(u[x])
			return 0;
		if(v[x])
			continue;
		if(!dfs(x))
			return 0;
	}
	u[n]=0;
	return 1;
}
void dfsa(int n)
{
	c[n]=u[n]=1;
	for(int x : a[n])
		if(!u[x])
			dfsa(x);
}
void dfsb(int n)
{
	c[n]=v[n]=1;
	for(int x : b[n])
		if(!v[x])
			dfsb(x);
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i=0,x,y;i<M;++i)
		scanf("%d%d", &x, &y), a[x].push_back(y), b[y].push_back(x);
	for(int i=1;i<=N;++i)
		if(!v[i])
			if(!dfs(i))
				return printf("-1\n"), 0;
	memset(u, 0, sizeof u);
	memset(v, 0, sizeof v);
	for(int i=1;i<=N;++i)
	{
		s[i] = "AE"[c[i]];
		ans += !c[i];
		if(!u[i]) dfsa(i);
		if(!v[i]) dfsb(i);
	}
	printf("%d\n%s\n", ans, s+1);
	return 0;
}


#include <cstdio>
#include <vector>

using namespace std;

const int MN = 2e5 + 10;
std::vector<int> a[MN], b[MN];
int N, M, ans;
bool u[MN], v[MN], c[MN];
char s[MN];
bool dfs(int n)
{
	u[n]=v[n]=1;
	for(int x : a[n])
	{
		if(u[x])
			return 0;
		if(v[x])
			continue;
		if(!dfs(x))
			return 0;
	}
	u[n]=0;
	return 1;
}
void dfsa(int n)
{
	c[n]=u[n]=1;
	for(int x : a[n])
		if(!u[x])
			dfsa(x);
}
void dfsb(int n)
{
	c[n]=v[n]=1;
	for(int x : b[n])
		if(!v[x])
			dfsb(x);
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i=0,x,y;i<M;++i)
		scanf("%d%d", &x, &y), a[x].push_back(y), b[y].push_back(x);
	for(int i=1;i<=N;++i)
		if(!v[i])
			if(!dfs(i))
				return printf("-1\n"), 0;
	memset(u, 0, sizeof u);
	memset(v, 0, sizeof v);
	for(int i=1;i<=N;++i)
	{
		s[i] = "AE"[c[i]];
		ans += !c[i];
		if(!u[i]) dfsa(i);
		if(!v[i]) dfsb(i);
	}
	printf("%d\n%s\n", ans, s+1);
	return 0;
}


#include <cstdio>
#include <vector>

using namespace std;

const int MN = 2e5 + 10;
std::vector<int> a[MN], b[MN];
int N, M, ans;
bool u[MN], v[MN], c[MN];
char s[MN];
bool dfs(int n)
{
	u[n]=v[n]=1;
	for(int x : a[n])
	{
		if(u[x])
			return 0;
		if(v[x])
			continue;
		if(!dfs(x))
			return 0;
	}
	u[n]=0;
	return 1;
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i=0,x,y;i<M;++i)
		scanf("%d%d", &x, &y), a[x].push_back(y), b[y].push_back(x);
	for(int i=1;i<=N;++i)
		if(!v[i])
			if(!dfs(i))
				return printf("-1\n"), 0;
	for(int i=1;i<=N;++i)
	{
		s[i] = "AE"[c[i]];
		ans += !c[i];
		for(int x:a[i])
			c[x]=1;
		for(int x:b[i])
			c[x]=1;
	}
	printf("%d\n%s\n", ans, s+1);
	return 0;
}


#include <cstdio>
#include <vector>

using namespace std;

const int MN = 2e5 + 10;
std::vector<int> a[MN], b[MN];
int N, M, ans;
bool u[MN], v[MN], c[MN];
char s[MN];
bool dfs(int n)
{
	u[n]=v[n]=1;
	for(int x : a[n])
	{
		if(u[x])
			return 0;
		if(v[x])
			continue;
		if(!dfs(x))
			return 0;
	}
	u[n]=0;
	return 1;
}
int main(void)
{
	scanf("%d%d", &N, &M);
	for(int i=0,x,y;i<M;++i)
		scanf("%d%d", &x, &y), a[x].push_back(y), b[y].push_back(x);
	for(int i=1;i<=N;++i)
		if(!v[i])
			if(!dfs(i))
				return printf("-1\n");
	for(int i=1;i<=N;++i)
	{
		s[i] = "AE"[c[i]];
		ans += !c[i];
		for(int x:a[i])
			c[x]=1;
		for(int x:b[i])
			c[x]=1;
	}
	printf("%d\n%s\n", ans, s+1);
	return 0;
}


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

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
using uid = uniform_int_distribution<int>;

using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using ordered_multiset = tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int inf = int(1e9) + 7;
const ll INF = ll(1e18) + 7;

#define X first
#define Y second

mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

int rand(int a, int b) {
	return uid(a, b)(rng);
}

void boost() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

int n, m;
bool exi[200007];
vector<int> G[200007];
int vis[200007];
bool cycle;

void dfs(int w, int p) {
	if(vis[w] == 2)
		return ;
	if(vis[w] == 1) {
		cycle = 1;
		return ;
	}

	vis[w] = 1;
	for(int  u : G[w]) {
		if(u != p)
			dfs(u, w);
	}
	vis[w] = 2;
}

void solve() {
	scanf("%d%d", &n, &m);
	int res = n;
	for(int i = 0 ; i < m ; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		if(!exi[b])
			res--;
		exi[b] = 1;
	}

	dfs(1, 0);

	if(cycle) res = -1;
	printf("%d\n", res);
	if(!cycle) {
		for(int i = 1 ; i <= n ; i++)
			printf("%c", exi[i] ? 'E' : 'A');
		printf("\n");
	}
}

int main() {
	//~ boost();
	int t = 1;
	//~ scanf("%d", &t);
	while(t--) {
		solve();
	}
	return 0;
}


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

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
using uid = uniform_int_distribution<int>;

using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using ordered_multiset = tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int inf = int(1e9) + 7;
const ll INF = ll(1e18) + 7;

#define X first
#define Y second

mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

int rand(int a, int b) {
	return uid(a, b)(rng);
}

void boost() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

int n, m;
bool exi[200007];
vector<int> G[200007];
int vis[200007];
bool cycle;

void dfs(int w, int p) {
	if(vis[w] == 2)
		return ;
	if(vis[w] == 1) {
		cycle = 1;
		return ;
	}

	vis[w] = 1;
	for(int  u : G[w]) {
		dfs(u, w);
	}
	vis[w] = 2;
}

void solve() {
	scanf("%d%d", &n, &m);
	int res = n;
	for(int i = 0 ; i < m ; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		if(a > b)
			swap(a, b);
		if(!exi[b])
			res--;
		exi[b] = 1;
	}

	dfs(1, 0);

	if(cycle) res = -1;
	printf("%d\n", res);
	if(!cycle) {
		for(int i = 1 ; i <= n ; i++)
			printf("%c", exi[i] ? 'E' : 'A');
		printf("\n");
	}
}

int main() {
	//~ boost();
	int t = 1;
	//~ scanf("%d", &t);
	while(t--) {
		solve();
	}
	return 0;
}


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

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
using uid = uniform_int_distribution<int>;

using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using ordered_multiset = tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int inf = int(1e9) + 7;
const ll INF = ll(1e18) + 7;

#define X first
#define Y second

mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

int rand(int a, int b) {
	return uid(a, b)(rng);
}

void boost() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

int n, m;
bool exi[200007];
vector<int> G[200007];
int vis[200007];
bool cycle;

void dfs(int w, int p) {
	if(vis[w] == 2)
		return ;
	if(vis[w] == 1) {
		cycle = 1;
		return ;
	}

	vis[w] = 1;
	for(int  u : G[w]) {
		dfs(u, w);
	}
	vis[w] = 2;
}

void solve() {
	scanf("%d%d", &n, &m);
	int res = n;
	for(int i = 0 ; i < m ; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		if(!exi[b])
			res--;
		exi[b] = 1;
	}

	dfs(1, 0);

	if(cycle) res = -1;
	printf("%d\n", res);
	if(!cycle) {
		for(int i = 1 ; i <= n ; i++)
			printf("%c", exi[i] ? 'E' : 'A');
		printf("\n");
	}
}

int main() {
	//~ boost();
	int t = 1;
	//~ scanf("%d", &t);
	while(t--) {
		solve();
	}
	return 0;
}


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

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
using uid = uniform_int_distribution<int>;

using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using ordered_multiset = tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int inf = int(1e9) + 7;
const ll INF = ll(1e18) + 7;

#define X first
#define Y second

mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

int rand(int a, int b) {
	return uid(a, b)(rng);
}

void boost() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

int n, m;
bool exi[200007];
vector<int> G[200007], GT[200007];
int vis[200007], vis2[200007];
bool cycle;

void dfs(int w, int p) {
	if(vis[w] == 2)
		return ;
	if(vis[w] == 1) {
		cycle = 1;
		return ;
	}

	vis[w] = 1;
	for(int  u : G[w]) {
		dfs(u, w);
	}
	vis[w] = 2;
}

void dfs2(int w) {
	if(vis[w])
		return ;
	vis[w] = 1;
	for(int u : G[w])
		dfs2(u);
}

void dfs3(int w) {
	if(vis2[w])
		return ;
	vis2[w] = 1;
	for(int u : GT[w])
		dfs3(u);
}

void solve() {
	scanf("%d%d", &n, &m);
	for(int i = 0 ; i < m ; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		GT[b].push_back(a);
	}

	for(int i = 1 ; i <= n ; i++)
		dfs(i, 0);

	if(cycle) {
		printf("-1\n");
		return ;
	}

	memset(vis, 0, sizeof vis);
	int res = 0;
	for(int i = 1 ; i <= n ; i++) {
		if(!vis[i] && !vis2[i]) {
			exi[i] = 1;
			res++;
		}
		dfs2(i);
		dfs3(i);
	}

	printf("%d\n", res);
	if(!cycle) {
		for(int i = 1 ; i <= n ; i++)
			printf("%c", exi[i] ? 'A' : 'E');
		printf("\n");
	}
}

int main() {
	//~ boost();
	int t = 1;
	//~ scanf("%d", &t);
	while(t--) {
		solve();
	}
	return 0;
}


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

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ii = pair<int, int>;
using pll = pair<ll, ll>;
using uid = uniform_int_distribution<int>;

using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;
using ordered_multiset = tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int inf = int(1e9) + 7;
const ll INF = ll(1e18) + 7;

#define X first
#define Y second

mt19937 rng(chrono::steady_clock().now().time_since_epoch().count());

int rand(int a, int b) {
	return uid(a, b)(rng);
}

void boost() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

int n, m;
bool exi[200007];
vector<int> G[200007], GT[200007];
int vis[200007], vis2[200007];
bool cycle;

void dfs(int w, int p) {
	if(vis[w] == 2)
		return ;
	if(vis[w] == 1) {
		cycle = 1;
		return ;
	}

	vis[w] = 1;
	for(int  u : G[w]) {
		dfs(u, w);
	}
	vis[w] = 2;
}

void dfs2(int w) {
	if(vis[w])
		return ;
	vis[w] = 1;
	for(int u : G[w])
		dfs2(u);
}

void dfs3(int w) {
	if(vis2[w])
		return ;
	vis2[w] = 1;
	for(int u : GT[w])
		dfs3(u);
}

void solve() {
	scanf("%d%d", &n, &m);
	for(int i = 0 ; i < m ; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		G[a].push_back(b);
		GT[b].push_back(a);
	}

	dfs(1, 0);

	if(cycle) {
		printf("-1\n");
		return ;
	}

	memset(vis, 0, sizeof vis);
	int res = 0;
	for(int i = 1 ; i <= n ; i++) {
		if(!vis[i] && !vis2[i]) {
			exi[i] = 1;
			res++;
		}
		dfs2(i);
		dfs3(i);
	}

	printf("%d\n", res);
	if(!cycle) {
		for(int i = 1 ; i <= n ; i++)
			printf("%c", exi[i] ? 'A' : 'E');
		printf("\n");
	}
}

int main() {
	//~ boost();
	int t = 1;
	//~ scanf("%d", &t);
	while(t--) {
		solve();
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

int fans=1;
int ans[200001];

void dfs(int pos)
{
    int i;

    vis[pos]=true;
    for(i=0;i<con[pos].size();i++){
        int f=con[pos][i];
        if(ans[f]==0)
            ans[f]=1;
        if(!vis[f])
            dfs(f);
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), du[x]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    for(i=1;i<=n;i++)
        if(ans[i]==0)
            dfs(i);

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001], fa[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

vector<int> top;
int up[200001];
int down[200001];

int fans=1;
int ans[200001];

void calup()
{
    int i, j;

    for(i=0;i<n;i++){
        int f=top[i];
        up[f]=f;
        for(j=0;j<fa[f].size();j++){
            int f2=fa[f][j];
            up[f]=min(up[f], up[f2]);
        }
        if(up[f]<f)
            ans[f]=1;
    }
}

void caldown()
{
    int i, j;

    for(i=n-1;i>=0;i--){
        int f=top[i];
        down[f]=f;
        for(j=0;j<con[f].size();j++){
            int f2=con[f][j];
            down[f]=min(down[f], down[f2]);
        }
        if(down[f]<f)
            ans[f]=1;
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), fa[x].pb(y), du[x]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        top.pb(cur);
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    if(fans){
        calup();
        caldown();
    }

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

int fans=1;
int ans[200001];

void dfs(int pos)
{
    int i;

    vis[pos]=true;
    for(i=0;i<con[pos].size();i++){
        int f=con[pos][i];
        if(ans[f]==0)
            fans=0;
        if(!vis[f])
            dfs(f);
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), du[max(x, y)]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    for(i=1;i<=n;i++)
        if(ans[i]==0)
            dfs(i);

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;

int fans=0;
int ans[200001];

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[x].pb(y), du[y]++;
        ans[y]=1;
    }

    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), fans++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }

    if(fans==n){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

int fans=1;
int ans[200001];

void dfs(int pos)
{
    int i;

    vis[pos]=true;
    for(i=0;i<con[pos].size();i++){
        int f=con[pos][i];
        if(ans[f]==0)
            fans=0;
        if(!vis[f])
            dfs(f);
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), du[x]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

int fans=1;
int ans[200001];

void wk(int pos)
{
    int i;

    vis[pos]=true;
    for(i=0;i<con[pos].size();i++){
        int f=con[pos][i];
        if(ans[f]==0)
            fans=0;
        if(!vis[f])
            wk(f);
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), du[max(x, y)]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    for(i=1;i<=n;i++)
        if(ans[i]==0)
            dfs(i);

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

#define pb push_back

using namespace std;

int n, m;
vector<int> con[200001];
int du[200001];

queue<int> pos;
bool vis[200001];

int fans=1;
int ans[200001];

void dfs(int pos)
{
    int i;

    vis[pos]=true;
    for(i=0;i<con[pos].size();i++){
        int f=con[pos][i];
        if(ans[f]==0)
            fans=0;
        if(!vis[f])
            dfs(f);
    }
}

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

    int i;

    cin >> n >> m;
    for(i=1;i<=m;i++){
        int x, y;
        cin >> x >> y;
        con[y].pb(x), du[x]++;
        ans[max(x, y)]=1;
    }

    int ct=0;
    for(i=1;i<=n;i++)
        if(du[i]==0)
            pos.push(i);
    while(!pos.empty()){
        int cur=pos.front();
        pos.pop(), ct++;
        for(i=0;i<con[cur].size();i++){
            int f=con[cur][i];
            du[f]--;
            if(du[f]==0)
                pos.push(f);
        }
    }
    if(ct!=n)
        fans=0;

    for(i=1;i<=n;i++)
        if(ans[i]==0)
            dfs(i);

    if(fans){
        int ct=0;
        for(i=1;i<=n;i++)
            if(ans[i]==0)
                ct++;
        cout << ct << endl;
        for(i=1;i<=n;i++){
            if(ans[i]==0)
                cout << 'A';
            else
                cout << 'E';
        }
        cout << endl;
    }
    else
        cout << -1 << endl;

    return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-05-06 22:33:23
 * @LastEditTime: 2020-05-07 15:24:05
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const int N = 2e5+7;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;

int n, m;
int a[N], tot;
int dp[N];
int ind[N], otd[N], vis[N];
vector<int> e[N], re[N];

inline bool bfs(const int &s) {
    static queue<int> q;
    vis[s] = s;
    q.push(s);
    while (q.size()) {
        int u = q.front();
        q.pop();
        for (const int &v : e[u]) {
            if (vis[v] == s) return true;
            if (vis[v]) continue;
            vis[v] = s;
            q.push(v);
        }
    }
    return false;
}

signed main()
{
    static queue<int> q;
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    for (int i = 1, u, v; i <= m; ++i) {
        cin >> u >> v;
        e[u].emplace_back(v);
        re[v].emplace_back(u);
        ++ind[v];
        ++otd[u];
    }
    for (int i = 1; i <= n; ++i) {
        if (!ind[i]) q.push(i);
        dp[i] = i;
    }
    while (q.size()) {
        int u = q.front();
        q.pop();
        a[++tot] = u;
        for (const int &v : e[u]) {
            if (--ind[v] == 0) q.push(v);
        }
    }
    if (tot < n) return cout << -1 << endl, 0;

    int res = 0;
    for (int i = n, u; i; --i) {
        u = a[i];
        for (const int &v : e[u]) {
            dp[u] = min(dp[u], dp[v]);
        }
    }
    for (int i = 1, u; i <= n; ++i) {
        u = a[i];
        for (const int &v : re[u]) {
            dp[u] = min(dp[u], dp[v]);
        }
    }
    for (int i = 1; i <= n; ++i) res += dp[i] == i;
    cout << res << endl;
    for (int i = 1; i <= n; ++i) {
        cout << (dp[i] == i ? "A" : "E");
    }
    cout << endl;
    return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-05-06 22:33:23
 * @LastEditTime: 2020-05-07 15:44:53
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const int N = 2e5+7;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;

int n, m;
int a[N], tot;
int dp[N];
int ind[N], otd[N], vis[N], rvis[N];
vector<int> e[N], re[N];

inline void bfs(const int &s, const vector<int> *e, int *vis) {
    static queue<int> q;
    vis[s] = 1;
    q.push(s);
    while (q.size()) {
        int u = q.front();
        q.pop();
        for (const int &v : e[u]) {
            if (vis[v]) continue;
            vis[v] = 1;
            q.push(v);
        }
    }
}

signed main()
{
    static queue<int> q;
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    for (int i = 1, u, v; i <= m; ++i) {
        cin >> u >> v;
        e[u].emplace_back(v);
        re[v].emplace_back(u);
        ++ind[v];
        ++otd[u];
    }
    for (int i = 1; i <= n; ++i) {
        if (!ind[i]) q.push(i);
    }
    while (q.size()) {
        int u = q.front();
        q.pop();
        a[++tot] = u;
        for (const int &v : e[u]) {
            if (--ind[v] == 0) q.push(v);
        }
    }
    if (tot < n) return cout << -1 << endl, 0;

    int res = 0;
    for (int i = 1; i <= n; ++i) {
        if (!vis[i] && !rvis[i]) {
            ++res;
            dp[i] = 1;
        }
        bfs(i, e, vis);
        bfs(i, re, rvis);
    }
    cout << res << endl;
    for (int i = 1; i <= n; ++i) cout << (dp[i] ? "A" : "E");
    cout << endl;
    /*
    for (int i = n, u; i; --i) {
        u = a[i];
        for (const int &v : e[u]) {
            dp[u] = min(dp[u], dp[v]);
        }
    }
    for (int i = 1, u; i <= n; ++i) {
        u = a[i];
        for (const int &v : re[u]) {
            dp[u] = min(dp[u], dp[v]);
        }
    }
    for (int i = 1; i <= n; ++i) res += dp[i] == i;
    cout << res << endl;
    for (int i = 1; i <= n; ++i) {
        cout << (dp[i] == i ? "A" : "E");
    }
    cout << endl;
    */
    return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-05-06 22:33:23
 * @LastEditTime: 2020-05-07 00:15:09
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const int N = 2e5+7;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;

int n, m;
int ind[N], otd[N], vis[N];
vector<int> e[N];

inline bool bfs(const int &s) {
    static queue<int> q;
    vis[s] = s;
    q.push(s);
    while (q.size()) {
        int u = q.front();
        q.pop();
        for (const int &v : e[u]) {
            if (vis[v] == s) return true;
            vis[v] = s;
            q.push(v);
        }
    }
    return false;
}

signed main()
{
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    for (int i = 1, u, v; i <= m; ++i) {
        cin >> u >> v;
        e[u].emplace_back(v);
        ++ind[v];
        ++otd[u];
    }
    for (int i = 1; i <= n; ++i) {
        if (vis[i]) continue;
        if (bfs(i)) return cout << -1 << endl, 0;
    }
    int cnti = 0, cnto = 0;
    for (int i = 1; i <= n; ++i) {
        if (!ind[i]) ++cnti;
        if (!otd[i]) ++cnto;
    }
    int *arr = ind;
    if (cnti < cnto) swap(cnti, cnto), arr = otd;
    cout << cnti << endl;
    for (int i = 1; i <= n; ++i) {
        cout << (arr[i] ? "E" : "A");
    }
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <climits>
using namespace std;
const int maxn = 2 * 1e5 +10;
long long n,k,x;
long long a[maxn];
long long pre[maxn],tail[maxn];
int main(){
    while(~scanf("%I64d%I64d%I64d",&n,&k,&x)){
        memset(pre,0,sizeof(pre));
        for(int i=1;i<=n;i++)
            scanf("%I64d",a + i),pre[i] = pre[i-1] | a[i];
        for(int i=n;i>=1;i--)
            tail[i] = tail[i+1] | a[i];
        long long x1 = x;
        for(int i=2;i<=k;i++)
            x *= x1;
        long long ans = 0;
        for(int i=1;i<=n;i++){
            long long temp = x * a[i];
            ans = max (ans ,temp | tail[i+1] | pre[i-1]);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;//
long long al[200030],qz[200030],hz[200030],q,ans=0,n;
int x,k;
int main(){
	scanf("%lld%d%d",&n,&k,&x);
	for(int i=1;i<=n;i++){
		scanf("%d",&al[i]);
		qz[i]=qz[i-1]|al[i];
	}
	for(int i=n;i>=1;i--)
		hz[i]=hz[i-1]|al[i];
	for(int i=1;i<=n;i++){
		long long w=al[i]*pow(x,k);
		q=hz[i+1]|qz[i-1]|w;
		ans=max(ans,q);
	}
	printf("%lld\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long al[200010],qz[200010],hz[200010],q,ans=0,n;
int x,k;//
int main(){
    scanf("%lld%d%d",&n,&k,&x);
    for(int i=1;i<=n;i++){
        scanf("%d",&al[i]);
        qz[i]=qz[i-1]|al[i];
    }
    for(int i=n;i>=1;i--)
        hz[i]=hz[i-1]|al[i];
    for(int i=1;i<=n;i++){
        long long w=al[i]*pow(x,k);
        q=hz[i+1]|qz[i-1]|w;
        ans=max(ans,q);
    }
    printf("%lld\n",ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long al[200030],qz[200030],hz[200030],q,ans=0,n;
int x,k;
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>k>>x;
	for(int i=1;i<=n;i++){
		cin>>al[i];
		qz[i]=qz[i-1]|al[i];
	}
	for(int i=n;i>=1;i--) hz[i]=hz[i+1]|al[i];
	int www=pow(x,k);
	for(int i=1;i<=n;i++){
		long long w=al[i]*www;
		q=hz[i+1]|qz[i-1]|w;
		ans=max(ans,q);
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll   long long
//#define max 706000
#define gc getchar_unlocked
#define pc putchar_unlocked
//inline void get(int *p){register  int n=0,sign=1,a=gc();while(a<'0'||a>'9'){ if(a=='-'){sign=-1;a=gc();break;} a=gc();}while(a>='0' && a<='9'){n=(n<<1)+(n<<3)+a-'0';a=gc();}*p=n*sign;}

//inline void put(int n){char d[10];int i=0;if(n<0){pc('-');n=-n;}do{d[i++]=n%10+'0';n=n/10;}while(n);while(i)pc(d[--i]);pc('\n');}
#define modu 1000000007
int modular_pow(int  base, int  exponent)
{
     int result = 1;
    while (exponent > 0)
    {
        if (exponent % 2 == 1)
            result = (result * base);
        exponent = exponent >> 1;
        base = (base * base);
    }
    return result;
}

 int gcd(ll int a,ll int b){
    if(b==0)
    return a;//gcd
    else return gcd(b,a%b);
 }

bool chek(int x){
    return (x&&!(x&(x-1)));// power of 2
}
vector<ll int>a;
vector<ll int>suff;
vector<ll int>pre;
int main() {
    std::ios::sync_with_stdio(false);
    ll int n,k,x;
     scanf("%lld",&n);scanf("%lld",&k);scanf("%lld",&x);
     a=vector<ll int>(n+3,0);
    pre=vector<ll int>(n+3,0);
    suff=vector<ll int>(n+3,0);
    for(ll int u=1;u<=n;u++){
        scanf("%lld",&a[u]);
        //if(u==1)
        //pre[u-1]=;
    }
    pre[0]=0;
    suff[n+1]=0;
    ll int uu;
    for(ll int r=1;r<=k;r++)
    {
        uu*=x;
    }
    for(ll int u=1;u<=n;u++){
        if(u==1)
        pre[u]=a[u];
        else
        pre[u]=pre[u-1]|a[u];
    }
    for(ll int u=n;u>=1;u--){
        if(u==n)
        suff[u]=a[u];
        else suff[u]=suff[u+1]|a[u];
    }
    ll int ans1;
    for(ll int u=1;u<=n;u++){
        if(u==1)
        ans1=pre[u-1]|suff[u+1]|a[u]*uu;
        else
        ans1=max(ans1,pre[u-1]|suff[u+1]|a[u]*uu);
    }
    printf("%lld\n",ans1);
    a.clear();pre.clear();suff.clear();
return 0;}


#include<bits/stdc++.h>
using namespace std;
#define ll   long long
//#define max 706000
#define gc getchar_unlocked
#define pc putchar_unlocked
//inline void get(int *p){register  int n=0,sign=1,a=gc();while(a<'0'||a>'9'){ if(a=='-'){sign=-1;a=gc();break;} a=gc();}while(a>='0' && a<='9'){n=(n<<1)+(n<<3)+a-'0';a=gc();}*p=n*sign;}

//inline void put(int n){char d[10];int i=0;if(n<0){pc('-');n=-n;}do{d[i++]=n%10+'0';n=n/10;}while(n);while(i)pc(d[--i]);pc('\n');}
#define modu 1000000007
int modular_pow(int  base, int  exponent)
{
     int result = 1;
    while (exponent > 0)
    {
        if (exponent % 2 == 1)
            result = (result * base);
        exponent = exponent >> 1;
        base = (base * base);
    }
    return result;
}

 int gcd(ll int a,ll int b){
    if(b==0)
    return a;//gcd
    else return gcd(b,a%b);
 }

bool chek(int x){
    return (x&&!(x&(x-1)));// power of 2
}
ll int a[200004];
int main() {
    std::ios::sync_with_stdio(false);
    int n,k,x;
    cin>>n>>k>>x;
    for(int u=0;u<=n-1;u++){
        scanf("%lld",&a[u]);
    }
    sort(a,a+n);
    for(int u=1;u<=k;u++){
        a[n-1]*=x;
    }
    ll int ans;
    for(int u=0;u<n;u++){
        if(u==0)
        ans=a[u];
        else ans=ans|a[u];
    }
    cout<<ans<<endl;
return 0;}


#include<bits/stdc++.h>
using namespace std;
#define ll   long long
//#define max 706000
#define gc getchar_unlocked
#define pc putchar_unlocked
//inline void get(int *p){register  int n=0,sign=1,a=gc();while(a<'0'||a>'9'){ if(a=='-'){sign=-1;a=gc();break;} a=gc();}while(a>='0' && a<='9'){n=(n<<1)+(n<<3)+a-'0';a=gc();}*p=n*sign;}

//inline void put(int n){char d[10];int i=0;if(n<0){pc('-');n=-n;}do{d[i++]=n%10+'0';n=n/10;}while(n);while(i)pc(d[--i]);pc('\n');}
#define modu 1000000007
int modular_pow(int  base, int  exponent)
{
     int result = 1;
    while (exponent > 0)
    {
        if (exponent % 2 == 1)
            result = (result * base);
        exponent = exponent >> 1;
        base = (base * base);
    }
    return result;
}

 int gcd(ll int a,ll int b){
    if(b==0)
    return a;//gcd
    else return gcd(b,a%b);
 }

bool chek(int x){
    return (x&&!(x&(x-1)));// power of 2
}
ll int a[2000004];
ll int pre[2000004];
ll int suff[2000004];
int main() {
    std::ios::sync_with_stdio(false);
    ll int n,k,x;
     scanf("%lld",&n);scanf("%lld",&k);scanf("%lld",&x);
    for(ll int u=1;u<=n;u++){
        scanf("%lld",&a[u]);
        //if(u==1)
        //pre[u-1]=;
    }
    ll int uu=1;
    for(ll int r=1;r<=k;r++)
    {
        uu*=x;
    }
    for(ll int u=1;u<=n;u++){
        if(u==0)
        pre[u]=a[u];
        else
        pre[u]=pre[u-1]|a[u];
    }
    for(ll int u=n;u>=1;u--){
        if(u==n-1)
        suff[u]=a[u];
        else suff[u]=suff[u-1]|a[u];
    }
    ll int ans1=INT_MIN;
    for(ll int u=1;u<=n;u++){
        if(u==1)
        ans1=pre[u-1]|suff[u+1]|a[u]*uu;
        else
        ans1=max(ans1,pre[u-1]|suff[u+1]|a[u]*uu);
    }
    printf("%lld\n",ans1);
return 0;}