//Be Name Khoda, Besmellah Rahmane Rahim, In The Name Of God;
//#include<bits/stweight++.h>
#include<iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <queue>
#include <deque>
#include <map>
#include <stack>
#include<bitset>
#include<list>
#include<cassert>
#include<numeric>
#include <stdio.h>
#include <string.h>
#include<iomanip>
#include<unordered_map>
#include<unordered_set>
#include <fstream>

using namespace std;

const int N = 1e5 + 5;
vector <int> graph[N];
set < pair< double, int> > s;
set< pair< double, int> > city;
bool isBad[N];
int around[N];
int all[N];
double a[N];
double b[N];
bool mark[N];
int n, m, k;
double ans = 0;

int main()
{
    cin >> n >> m >> k;
    for (int i = 0; i < k; i++)
    {
        int tmp;
        cin >> tmp;
        tmp--;
        isBad[tmp] = true;
    }
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        graph[u - 1].push_back(v - 1);
        graph[v - 1].push_back(u - 1);
    }
    for (int i = 0; i < n; i++)
    {
        int m1 = 0;
        int m2 = graph[i].size();
        for (auto nei: graph[i])
        {
            if (isBad[nei])
            {
                m1++;
            }
        }
        around[i] = m2 - m1;
        all[i] = m2;
        m1 = m2 - m1;
        a[i] =  (double) m1 / m2;
        b[i] = a[i];
        if (isBad[i])
        {
            continue;
        }
        s.insert({a[i], i});
        city.insert({a[i], i});
    }
    ans = (*s.begin()).first;
    int step = 0;
    int cnt = 0;
    while (s.size())
    {
        cnt++;
        int v = (*s.begin()).second;
        mark[v] = true;
        s.erase(s.begin());
        for (auto nei: graph[v])
        {
            s.erase({a[nei], nei});
            around[nei]--;
            a[nei] = (double)around[nei] / all[nei];
            if (isBad[nei] || mark[nei])
            {
                continue;
            }
            s.insert({a[nei], nei});
        }
        if ((*s.begin()).first > ans)
        {
            step = cnt;
        }
        ans = max(ans, (*s.begin()).first);
    }
    cnt = 0;
    memset(mark, 0, sizeof mark);
    for (int i = 0; i < n; i++)
    {
        a[i] = b[i];
    }
    while (city.size())
    {
        if (step == cnt)
        {
            break;
        }
        cnt++;
        int v = (*city.begin()).second;
        mark[v] = true;
        city.erase(city.begin());
        for (auto nei: graph[v])
        {
            city.erase({a[nei], nei});
            around[nei]--;
            a[nei] = (double)around[nei] / all[nei];
            if (isBad[nei] || mark[nei])
            {
                continue;
            }
            city.insert({a[nei], nei});
        }
        ans = max(ans, (*city.begin()).first);
    }
    cout << city.size() << endl;
    for (auto nei: city)
    {
        cout << nei.second + 1 << " ";
    }

}


//Be Name Khoda, Besmellah Rahmane Rahim, In The Name Of God;
//#include<bits/stweight++.h>
#include<iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <queue>
#include <deque>
#include <map>
#include <stack>
#include<bitset>
#include<list>
#include<cassert>
#include<numeric>
#include <stdio.h>
#include <string.h>
#include<iomanip>
#include<unordered_map>
#include<unordered_set>
#include <fstream>

using namespace std;

const int N = 1e5 + 5;
vector <int> graph[N];
set < pair< long double, int> > s;
set< pair< long double, int> > city;
bool isBad[N];
int around[N];
int all[N];
long double a[N];
long double b[N];
bool mark[N];
int n, m, k;
long double ans = 0;

int main()
{
    cin >> n >> m >> k;
    for (int i = 0; i < k; i++)
    {
        int tmp;
        cin >> tmp;
        tmp--;
        isBad[tmp] = true;
    }
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        graph[u - 1].push_back(v - 1);
        graph[v - 1].push_back(u - 1);
    }
    for (int i = 0; i < n; i++)
    {
        int m1 = 0;
        int m2 = graph[i].size();
        for (auto nei: graph[i])
        {
            if (isBad[nei])
            {
                m1++;
            }
        }
        around[i] = m2 - m1;
        all[i] = m2;
        m1 = m2 - m1;
        a[i] =  (long double) m1 / m2;
        b[i] = a[i];
        if (isBad[i])
        {
            continue;
        }
        s.insert({a[i], i});
        city.insert({a[i], i});
    }
    ans = (*s.begin()).first;
    int step = 0;
    int cnt = 0;
    while (s.size())
    {
        cnt++;
        int v = (*s.begin()).second;
        mark[v] = true;
        s.erase(s.begin());
        for (auto nei: graph[v])
        {
            s.erase({a[nei], nei});
            around[nei]--;
            a[nei] = (long double)around[nei] / all[nei];
            if (isBad[nei] || mark[nei])
            {
                continue;
            }
            s.insert({a[nei], nei});
        }
        if ((*s.begin()).first > ans)
        {
            step = cnt;
        }
        ans = max(ans, (*s.begin()).first);
    }
    cnt = 0;
    memset(mark, 0, sizeof mark);
    for (int i = 0; i < n; i++)
    {
        a[i] = b[i];
    }
    while (city.size())
    {
        if (step == cnt)
        {
            break;
        }
        cnt++;
        int v = (*city.begin()).second;
        mark[v] = true;
        city.erase(city.begin());
        for (auto nei: graph[v])
        {
            city.erase({a[nei], nei});
            around[nei]--;
            a[nei] = (long double)around[nei] / all[nei];
            if (isBad[nei] || mark[nei])
            {
                continue;
            }
            city.insert({a[nei], nei});
        }
        ans = max(ans, (*city.begin()).first);
    }
    cout << city.size() << endl;
    for (auto nei: city)
    {
        cout << nei.second + 1 << " ";
    }

}


#include <iostream>
#include <vector>
#include <set>
using namespace std;

const int N = 100 * 1000 + 5;

bool df[N];
//vector <int> frt;
vector <int> adj[N];
bool mark[N];
double f[N];
double a[N];
set <pair <double, int> > s;
int ord[N];

int main() {
	int n, m, k;
	cin >> n >> m >> k;
	fill(f, f + n + 1, 1);
	for (int i = 0; i < k; i++) {
		int v;
		cin >> v;
		df[v] = true;
		f[v] = -1;
	}
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	//	if (!df[u]) {
	//		cnt[v]++;
	//	}
	//	else {
	//		cnt[u]++;
	//	}
	}
	for (int i = 1; i <= n; i++) {
		s.insert({f[i], i});
	}
	int ansfor = 1;
	while (s.size()) {
		int v = (*s.begin()).second;
		a[s.size()] = f[v];
		ord[v] = s.size();
	//	cout << "73 " << v << " " << f[v] << endl;
		if (f[v] > a[ansfor]) {
			ansfor = s.size();
		}
		s.erase(s.begin());
		mark[v] = true;
		for (auto u : adj[v]) {
			if (!mark[u]) {
				s.erase({f[u], u});
				f[u] -= (double) 1 / adj[u].size();
				s.insert({f[u], u});
			}
		}

	}
	cout << ansfor << endl;
	for (int i = 1; i <= n; i++) {
		if (ord[i] <= ansfor) {
			cout << i << " ";
		}
	}
	return 0;
}


#include <cstdio>
#include <vector>
#include <set>
#include <cassert>
#include <algorithm>

bool fort[100005];
std::vector<int> adj[100005];
bool own[100005];
int power[100005];

std::set<std::pair<double,int> > strength;

void lose(int x){
  assert(own[x]);
  own[x]=false;
  for(int y:adj[x]){
    if(own[y]){
      strength.erase({(double)power[y]/adj[y].size(),y});
      power[y]--;
      strength.insert({(double)power[y]/adj[y].size(),y});
    }
  }
}

int main(){
  int N,M,K;
  scanf("%d %d %d",&N,&M,&K);
  for(int i=0;i<K;i++){
    int F;
    scanf("%d",&F);
    F--;
    fort[F]=true;
  }
  for(int i=0;i<M;i++){
    int A,B;
    scanf("%d %d",&A,&B);
    A--,B--;
    adj[A].push_back(B);
    adj[B].push_back(A);
  }
  for(int i=0;i<N;i++){
    if(!fort[i]){
      own[i]=true;
    }
  }
  for(int i=0;i<N;i++){
    if(!own[i]) continue;
    for(int j:adj[i]){
      if(own[j]){
	power[i]++;
      }
    }
    strength.insert({(double)power[i]/adj[i].size(),i});
  }
  double best=-1;
  while(strength.size()>0){
    auto pair=*strength.begin();
    strength.erase(strength.begin());
    best=std::max(best,pair.first);
    lose(pair.second);
  }
  assert(strength.empty());
  std::fill(power,power+N,0);
  assert(std::count(own,own+N,false)==N);
  //fprintf(stderr,"best=%.10lf\n",best);
  for(int i=0;i<N;i++){
    if(!fort[i]){
      own[i]=true;
    }
  }
  for(int i=0;i<N;i++){
    if(!own[i]) continue;
    for(int j:adj[i]){
      if(own[j]){
	power[i]++;
      }
    }
    strength.insert({(double)power[i]/adj[i].size(),i});
  }
  while(strength.size()>0){
    auto pair=*strength.begin();
    strength.erase(strength.begin());
    //fprintf(stderr,"best=%.10lf, curr=%.10lf\n",best,pair.first);
    if(best==pair.first){
      printf("%d\n",(int)std::count(own,own+N,true));
      for(int i=0;i<N;i++){
	if(own[i]){
	  printf("%d ",i+1);
	}
      }
      printf("\n");
      return 0;
    }
    lose(pair.second);
  }
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
//#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stdio.h>
#include <cstdio>
#include <math.h>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <random>
#include <iomanip>
#include <bitset>

using namespace std;

template<typename T> void uin(T &a, T b) {
    if (b < a) {
        a = b;
    }
}

template<typename T> void uax(T &a, T b) {
    if (b > a) {
        a = b;
    }
}

#define int long long
#define ghost signed
#define left left228
#define right right228
#define complex complex228
#define count count228
#define sin sin228
#define list list228

const int N = 100 * 1000 + 228;

int n, m, k;
vector<int> g[N];
int deg[N], dg[N], _dg[N], take[N];
bool blocked[N], erased[N];

bool cmp(pair<int, int> a, pair<int, int> b) {
	return a.first * b.second < b.first * a.second;
}

set< pair<int, int> > s;

bool check(int a, int b) {
	s.clear();
	for (int i = 1; i <= n; ++i) dg[i] = _dg[i];
	for (int i = 1; i <= n; ++i) {
		if (blocked[i]) continue;
		take[i] = (a * deg[i] + b - 1) / b;
		s.insert({dg[i] - take[i], i});
		erased[i] = 0;
	}
	while (!s.empty()) {
		if (s.begin()->first >= 0) {
			break;
		}
		int v = s.begin()->second;
		erased[v] = 1;
		s.erase(s.begin());
		for (int to : g[v]) {
			if (!erased[to]) {
				s.erase({dg[to] - take[to], to});
				--dg[to];
				s.insert({dg[to] - take[to], to});
			}
		}
	}
	return !s.empty();
}

ghost main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
	cin >> n >> m >> k;
	for (int i = 1; i <= k; ++i) {
		int x;
		cin >> x;
		blocked[x] = 1;
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		++deg[u];
		++deg[v];
		if (!blocked[u] && !blocked[v]) {
			++dg[u], ++dg[v];
			g[u].push_back(v), g[v].push_back(u);
		}
	}
	for (int i = 1; i <= n; ++i) _dg[i] = dg[i];
	vector< pair<int, int> > vls;
	vls.emplace_back(0, 10);
	vls.emplace_back(1, 1);
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j < deg[i]; ++j) {
			vls.emplace_back(j, deg[i]);
		}
	}
	sort(vls.begin(), vls.end(), cmp);
	int l = 0, r = (int)vls.size();
	while (r - l > 1) {
		int mid = (l + r) >> 1;
		if (check(vls[mid].first, vls[mid].second)) l = mid;
		else r = mid;
	}
	check(vls[l].first, vls[l].second);
	cout << (int)s.size() << '\n';
	for (pair<int, int> i : s) cout << i.second << ' ';
	cout << '\n';
    return 0;
} // kek ;
// Ого! Кажетсья это $#@!


#include <bits/stdc++.h>

typedef long long LL;
const int MAXN = 1e5 + 10;
int head[MAXN], nxt[MAXN << 1], to[MAXN << 1], tot;
int deg[MAXN];
void adde(int b, int e) {
	nxt[++tot] = head[b]; to[head[b] = tot] = e;
	nxt[++tot] = head[e]; to[head[e] = tot] = b;
	++deg[b], ++deg[e];
}
bool cant[MAXN];
struct fr { int a, b; } anst[MAXN];
bool operator < (fr x, fr y) {
	return (LL) x.a * y.b > (LL) x.b * y.a;
}
typedef std::pair<fr, int> pi;
std::priority_queue<pi> q;
int cnt[MAXN];
int n, m, K;
int del[MAXN];
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> n >> m >> K;
	for (int i = 1, t; i <= K; ++i)
		std::cin >> t, cant[t] = true;
	for (int i = 1, b, e; i <= m; ++i)
		std::cin >> b >> e, adde(b, e);
	for (int i = 1; i <= n; ++i) if (!cant[i])
		for (int j = head[i]; j; j = nxt[j])
			++cnt[to[j]];
	fr ans = (fr) {1, 1};
	for (int i = 1; i <= n; ++i) if (!cant[i]) {
		fr now = (fr) {cnt[i], deg[i]};
		q.emplace(now, i);
		if (ans < now) ans = now;
	}
	int bak = 0, ansat = 1;
	while (!q.empty()) {
		fr s; int u;
		std::tie(s, u) = q.top(); q.pop();
		if (cant[u]) continue;
		del[++bak] = u; anst[bak] = s;
		if (s < ans) ans = s, ansat = bak;
		for (int i = head[u]; i; i = nxt[i])
			if (!cant[to[i]])
				q.emplace((fr) {--cnt[to[i]], deg[to[i]]}, to[i]);
		cant[u] = true;
	}
	for (int i = bak; i >= ansat; --i)
		cant[del[i]] = false;
	std::vector<int> ansl;
	for (int i = 1; i <= n; ++i) if (!cant[i]) ansl.push_back(i);
	std::cout << ansl.size() << '\n';
	for (auto t : ansl) std::cout << t << ' ';
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define int long long

using ld = long double;

void run();

signed main() { ios::sync_with_stdio(0); cin.tie(); cout << fixed << setprecision(13); run(); }

void print(vector<int> a) { for (int i : a) { cout << i << " "; } cout << endl; }

void run() {
    int n, m, k;
    cin >> n >> m >> k;

    vector<char> no(n, 0);

    for (int i = 0; i < k; ++i) {
        int a;
        cin >> a;
        --a;
        no[a] = 1;
    }

    vector<vector<int>> g(n);
    vector<int> cnt(n);

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u; --v;
        ++cnt[u]; ++cnt[v];
        if (!no[u] && !no[v]) {
            g[u].push_back(v);
            g[v].push_back(u);
        }
    }

    struct frac {
        int p, q;
        bool operator<(const frac& other) const {
            return p * other.q < q* other.p;
        }
    };
    vector<frac> rel = { {0, 1}, {0, 1} };
    for (int i = 0; i < n; ++i) {
        for (int j = 1; j < cnt[i]; ++j) {
            rel.push_back({ j, cnt[i] });
        }
    }
    rel.push_back({ 1, 1 });

    sort(rel.begin(), rel.end());

    size_t l = 0, r = rel.size() - 1;

    vector<char> ans;
    while (l < r) {
        size_t mid = (l + r + 1) >> 1;
        frac need = rel[mid];
        vector<int> need_cnt(n), can(n);
        for (int i = 0; i < n; ++i) {
            can[i] = g[i].size();
            /* k : need <= k / cnt[i] => need.p * cnt[i] <= k * need.q, k >= (need.p * cnt[i]) / need.q
            */
            need_cnt[i] = (need.p * cnt[i]) / need.q;
            if ((need.p * cnt[i]) % need.q)
                ++need_cnt[i];
        }

        queue<int> cant;
        for (int i = 0; i < n; ++i) {
            if (need_cnt[i] > g[i].size())
                cant.push(i);
        }

        vector<char> vis = no;
        while (!cant.empty()) {
            int cur = cant.front();
            vis[cur] = 1;
            cant.pop();

            for (int i : g[cur]) {
                if (need_cnt[i] <= can[i]) {
                    --can[i];
                    if (need_cnt[i] > can[i]) {
                        vis[i] = 1;
                        cant.push(i);
                    }
                }
            }
        }

        char mmm = 1;
        for (int i = 0; i < n; ++i) {
            mmm &= vis[i];
        }
        if (mmm) {
            r = mid - 1;
        } else {
            ans = vis;
            l = mid;
        }
    }
    vector<int> rr;
    for (int i = 0; i < n; ++i) {
        if (!ans[i]) {
            rr.push_back(i + 1);
        }
    }

    cerr << rel[l].p << "/" << rel[l].q << endl;
    cout << rr.size() << endl;
    for (int i : rr) { cout << i << " "; }
}


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

const int maxn = 1e5 + 10;
const double eps = 1e-6;

int n, m, k, u, v;
vector<int> vc[maxn];
queue<int> q;
int sz[maxn], _sz[maxn], __sz[maxn], a[maxn];
bool vis[maxn];

bool check (double x)
{
    while(q.size()) q.pop();
    memset (vis, 0, sizeof vis);
    for (int i = 1; i <= k; i++) vis[a[i]] = 1;
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]) continue;
        __sz[i] = _sz[i];
        if ((double)__sz[i] / (double)sz[i] < x) q.push(i);
    }
    while (q.size())
    {
        int now = q.front(); q.pop();
        if (vis[now]) continue;
        vis[now] = true;
        for (auto it : vc[now])
        {
            __sz[it]--;
            if ((double)__sz[it] / (double)sz[it] < x) q.push(it);
        }
    }
    bool ok = false;
    for (int i = 1; i <= n; i++) if (!vis[i]) ok = true;
    return ok;
}

int main()
{
    //freopen("C:/Users/MACHENIKE/Desktop/data.in","r",stdin);
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= k; i++) scanf("%d", a + i);
    for (int i = 1; i <= m; i++)
    {
        scanf("%d %d", &u, &v);
        vc[u].push_back (v);
        vc[v].push_back (u);
        sz[u]++, sz[v]++;
        _sz[u]++, _sz[v]++;
    }
    for (int i = 1; i <= k; i++) for (auto it : vc[a[i]]) _sz[it]--;
    double st = 0.0, ed = 1.0, ans = 0;
    for (int i = 1; i <= 100; i++)
    {
        double mid = (st + ed) / 2;
        if (check (mid))
        {
            st = mid;
            ans = mid;
        }
        else ed = mid - eps;
    }
    check (ans);
    vector<int> A;
    for (int i = 1; i <= n; i++) if (!vis[i]) A.push_back(i);
    printf("%d\n", A.size());
    for (auto it : A) printf("%d ", it);
    return 0;
}


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

const int maxn = 1e5 + 10;
const double eps = 1e-8;

int n, m, k, u, v;
vector<int> vc[maxn];
queue<int> q;
int sz[maxn], _sz[maxn], __sz[maxn], a[maxn];
bool vis[maxn];

bool check (double x)
{
    while(q.size()) q.pop();
    memset (vis, 0, sizeof vis);
    for (int i = 1; i <= k; i++) vis[a[i]] = 1;
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]) continue;
        __sz[i] = _sz[i];
        if ((double)__sz[i] / (double)sz[i] < x) q.push(i);
    }
    while (q.size())
    {
        int now = q.front(); q.pop();
        if (vis[now]) continue;
        vis[now] = true;
        for (auto it : vc[now])
        {
            __sz[it]--;
            if ((double)__sz[it] / (double)sz[it] < x && !vis[it]) q.push(it);
        }
    }
    bool ok = false;
    for (int i = 1; i <= n; i++) if (!vis[i]) ok = true;
    return ok;
}

int main()
{
    //freopen("C:/Users/MACHENIKE/Desktop/data.in","r",stdin);
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= k; i++) scanf("%d", a + i);
    for (int i = 1; i <= m; i++)
    {
        scanf("%d %d", &u, &v);
        vc[u].push_back (v);
        vc[v].push_back (u);
        sz[u]++, sz[v]++;
        _sz[u]++, _sz[v]++;
    }
    for (int i = 1; i <= k; i++) for (auto it : vc[a[i]]) _sz[it]--;
    double st = 0.0, ed = 1.0, ans = 0;
    for (int i = 1; i <= 200; i++)
    {
        double mid = (st + ed) / 2;
        if (check (mid))
        {
            st = mid;
            ans = mid;
        }
        else ed = mid - eps;
    }
    check (ans);
    vector<int> A;
    for (int i = 1; i <= n; i++) if (!vis[i]) A.push_back(i);
    printf("%d\n", A.size());
    for (auto it : A) printf("%d ", it);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
const int MAXN = 100100;

int gtot[MAXN] , g[MAXN];
bool vis[MAXN];
vector<int> grafo[MAXN];

signed main(){
	memset(g,0,sizeof g);
	memset(gtot,0,sizeof gtot);

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

	vector<int> vec;

	for(int i = 1;i <= k;i++){
		int x;
		cin >> x;
		vec.push_back(x);
	}

	for(int i = 1;i <= m;i++){
		int x,y;
		cin >> x >> y;
		grafo[x].push_back(y) , grafo[y].push_back(x);
		gtot[x] ++ , gtot[y] ++;
		g[x] ++ , g[y] ++;
	}

	priority_queue<pair<long double,int>,vector<pair<long double,int>>,greater<pair<long double,int>>> fila;

	for(int i = 0;i < k;i++){
		int at = vec[i];
		vis[at] = true;
		for(int j = 0;j < grafo[at].size();j++){
			int t = grafo[at][j];
			g[t] --;
		}
	}

	for(int i = 1;i <= n;i++) fila.push({(long double) g[i]/(long double) gtot[i],i});

	vector<int> resp;
	pair<long double,int> res = {-1,1000000};

	while(!fila.empty()){
		pair<long double,int> at = fila.top();
		if(vis[at.second] == true){
			fila.pop();
			continue;
		}
		if(vis[at.second] == false) resp.push_back(at.second);
		if(vis[at.second] == false && res.first < at.first) res = at;

		//cout << "/ " << at.second << endl;

		if(vis[at.second] == false){
			for(int i = 0;i < grafo[at.second].size();i++){
				int t = grafo[at.second][i];
				g[t] --;
				//cout << "| " << at.second << " " << t << endl;
				if(vis[t] == false) fila.push({(long double) g[t]/(long double)gtot[t],t});
			}
		}

		vis[at.second] = true;
	}

	bool f = false;
	//cout << res.first << " " << res.second << endl;
	for(int i = 0;i < resp.size();i++){
		if(resp[i] == res.second) f = true , cout << (int) resp.size() - i << endl;
		if(f == true) cout << resp[i] << " ";
	}

}


#ifdef ONPC
# define _GLIBCXX_DEBUG
#define deb(a) cerr << "nu smotri pidor " << #a << " = " << a << endl;
#else
#define deb(a)
#endif
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;

typedef long long ll;
typedef long double ld;
ll MOD = 1e9 + 7;

const int N = 200000;
ll used[N];
vector<ll> gr[N];
ld eps = 1e-8;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout << fixed << setprecision(20);
    ll n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; i++){
        ll tmp;
        cin >> tmp;
        tmp--;
        used[tmp] = 2;
    }
    for (int i = 0; i < m; i++){
        ll u, v;
        cin >> u >> v;
        u--, v--;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    ld L = 0, R = 1;
    vector<ll> ans;
    while (R - L > eps){
        ld mid = (L + R) / 2;
        vector<ll> st(n);
        vector<ll> st2(n);
        queue<ll> q;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                st[i] = ceil(gr[i].size() * mid);
            }
            ll kol = 0;
            for (auto j : gr[i]){
                if (!used[j]){
                    kol++;
                }
            }
            st2[i] = kol;
            if(kol < st[i]){
                q.push(i);
                used[i] = 1;
            }
        }
        while (q.size()){
            ll v = q.front();
            q.pop();
            for (auto j : gr[v]){
                if (!used[j]){
                    st2[j]--;
                    if (st2[j] < st[j]){
                        used[j] = 1;
                        q.push(j);
                    }
                }
            }
        }
        vector<ll> an;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                an.push_back(i);
            }
            else{
                if (used[i] == 1){
                    used[i] = 0;
                }
            }
        }
        if (an.size()){
            ans = an;
            L = mid;
        }
        else{
            R = mid;
        }
    }
    //cout << L;
    cout << ans.size() << endl;
    for (auto i : ans){
        cout << i + 1 << " ";
    }
#ifdef ONPC
    cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
}
//egor lox


#ifdef ONPC
# define _GLIBCXX_DEBUG
#define deb(a) cerr << "nu smotri pidor " << #a << " = " << a << endl;
#else
#define deb(a)
#endif
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;

typedef long long ll;
typedef long double ld;
ll MOD = 1e9 + 7;

const int N = 200000;
ll used[N];
vector<ll> gr[N];
ld eps = 1e-8;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout << fixed << setprecision(20);
    ll n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; i++){
        ll tmp;
        cin >> tmp;
        tmp--;
        used[tmp] = 2;
    }
    for (int i = 0; i < m; i++){
        ll u, v;
        cin >> u >> v;
        u--, v--;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    ld L = 0, R = 1;
    vector<ll> ans;
    while (R - L > eps){
        ld mid = (L + R) / 2;
        vector<ll> st(n);
        vector<ll> st2(n);
        queue<ll> q;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                st[i] = ceil(gr[i].size() * mid);
            }
            ll kol = 0;
            for (auto j : gr[i]){
                if (!used[j]){
                    kol++;
                }
            }
            st2[i] = kol;
            if(kol < st[i]){
                q.push(i);
                used[i] = 1;
            }
        }
        while (q.size()){
            ll v = q.front();
            q.pop();
            for (auto j : gr[v]){
                if (!used[j]){
                    st2[j]--;
                    if (st2[j] < st[j]){
                        used[j] = 1;
                        q.push(j);
                    }
                }
            }
        }
        vector<ll> an;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                an.push_back(i);
            }
            else{
                if (used[i] == 1){
                    used[i] = 0;
                }
            }
        }
        if (an.size()){
            ans = an;
            L = mid;
        }
        else{
            R = mid;
        }
    }
    //cout << L;
    if (!ans.size())
    {
        for (int i = 0; i < n; i++){
            if (!used[i]){
                cout << 1 << endl;
                cout << i + 1;
                return 0;
            }
        }
    }
    cout << ans.size() << endl;
    for (auto i : ans){
        cout << i + 1 << " ";
    }
#ifdef ONPC
    cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
}
//egor lox


#ifdef ONPC
# define _GLIBCXX_DEBUG
#define deb(a) cerr << "nu smotri pidor " << #a << " = " << a << endl;
#else
#define deb(a)
#endif
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;

typedef long long ll;
typedef long double ld;
ll MOD = 1e9 + 7;

const int N = 200000;
ll used[N];
vector<ll> gr[N];
ld eps = 1e-8;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout << fixed << setprecision(20);
    ll n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; i++){
        ll tmp;
        cin >> tmp;
        tmp--;
        used[tmp] = 2;
    }
    for (int i = 0; i < m; i++){
        ll u, v;
        cin >> u >> v;
        u--, v--;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    ld L = 0, R = 1;
    vector<ll> ans;
    while (R - L > eps){
        ld mid = (L + R) / 2;
        vector<ll> st(n);
        vector<ll> st2(n);
        queue<ll> q;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                st[i] = ceil(gr[i].size() * mid);
                ll kol = 0;
                for (auto j : gr[i]){
                    if (!used[j]){
                        kol++;
                    }
                }
                st2[i] = kol;
                if(kol < st[i]){
                    q.push(i);
                    used[i] = 1;
                }
            }
        }
        while (q.size()){
            ll v = q.front();
            q.pop();
            for (auto j : gr[v]){
                if (!used[j]){
                    st2[j]--;
                    if (st2[j] < st[j]){
                        used[j] = 1;
                        q.push(j);
                    }
                }
            }
        }
        vector<ll> an;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                an.push_back(i);
            }
            else{
                if (used[i] == 1){
                    used[i] = 0;
                }
            }
        }
        if (an.size()){
            ans = an;
            L = mid;
        }
        else{
            R = mid;
        }
    }
    //cout << L;
    if (!ans.size())
    {
        for (int i = 0; i < n; i++){
            if (!used[i]){
                cout << 1 << endl;
                cout << i + 1;
                return 0;
            }
        }
    }
    cout << ans.size() << endl;
    for (auto i : ans){
        cout << i + 1 << " ";
    }
#ifdef ONPC
    cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
}
//egor lox


#ifdef ONPC
# define _GLIBCXX_DEBUG
#define deb(a) cerr << "nu smotri pidor " << #a << " = " << a << endl;
#else
#define deb(a)
#endif
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;

typedef long long ll;
typedef long double ld;
ll MOD = 1e9 + 7;

const int N = 200000;
ll used[N];
vector<ll> gr[N];
ld eps = 1e-8;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout << fixed << setprecision(20);
    ll n, m, k;
    cin >> n >> m >> k;
    for(int i = 0; i < k; i++){
        ll tmp;
        cin >> tmp;
        tmp--;
        used[tmp] = 2;
    }
    for (int i = 0; i < m; i++){
        ll u, v;
        cin >> u >> v;
        u--, v--;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    ld L = 0, R = 1;
    vector<ll> ans;
    while (R - L > eps){
        ld mid = (L + R) / 2;
        vector<ll> st(n);
        vector<ll> st2(n);
        queue<ll> q;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                st[i] = ceil(gr[i].size() * mid);
                ll kol = 0;
                for (auto j : gr[i]){
                    if (!used[j]){
                        kol++;
                    }
                }
                st2[i] = kol;
            }
        }
        for (int i = 0; i < n; i++){
            if (!used[i]){
                if(st2[i] < st[i]){
                    q.push(i);
                    used[i] = 1;
                }
            }
        }
        while (q.size()){
            ll v = q.front();
            q.pop();
            for (auto j : gr[v]){
                if (!used[j]){
                    st2[j]--;
                    if (st2[j] < st[j]){
                        used[j] = 1;
                        q.push(j);
                    }
                }
            }
        }
        vector<ll> an;
        for (int i = 0; i < n; i++){
            if (!used[i]){
                an.push_back(i);
            }
            else{
                if (used[i] == 1){
                    used[i] = 0;
                }
            }
        }
        if (an.size()){
            ans = an;
            L = mid;
        }
        else{
            R = mid;
        }
    }
    //cout << L;
    if (!ans.size())
    {
        for (int i = 0; i < n; i++){
            if (!used[i]){
                cout << 1 << endl;
                cout << i + 1;
                return 0;
            }
        }
    }
    cout << ans.size() << endl;
    for (auto i : ans){
        cout << i + 1 << " ";
    }
#ifdef ONPC
    cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
}
//egor lox


#include <bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define PF push_front
#define MP make_pair
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int maxn = 1e5 + 10;
const int inf = 1e9;
int mark[maxn];
vector <int> g[maxn];
int d[maxn], dinset[maxn];

int main () {
	ios::sync_with_stdio(false);
	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 1; i <= k; i++) {
		int x;
		cin >> x;
		mark[x] = 1;
	}

	for (int i = 1; i <= m; i++) {
		int v, u;
		cin >> v >> u;
		g[v].PB (u);
		g[u].PB (v);
		d[v] ++;
		d[u] ++;
	}
	for (int v = 1; v <= n; v++) {
		if (mark[v] == false) {
			for (auto u : g[v]) {
				dinset[u] ++;
			}
		}
	}
	set <pair <ld, int> > s;
	for (int v = 1; v <= n; v++) {
		if (mark[v] == 0) {
			s.insert ({1. * dinset[v] / d[v], v});
		}
	}
	ld ans = 0;
	while (!s.empty()) {
		ans = max (ans, (*s.begin()).F);
		auto v = (*s.begin()).S;
		mark[v] = 2;
		s.erase (s.begin());
		for (auto u : g[v]) {
			if (mark[u] == 0) {
				s.erase ({1. * dinset[u] / d[u], u});
				dinset[u] --;
				s.insert ({1. * dinset[u] / d[u], u});
			}
		}
	}

	memset (dinset, 0, sizeof dinset);
	for (int v = 1; v <= n; v++) {
		if (mark[v] == 2) {
			for (auto u : g[v]) {
				dinset[u] ++;
			}
		}
	}
	s.clear();
	for (int v = 1; v <= n; v++) {
		if (mark[v] == 2) {
			s.insert ({1. * dinset[v] / d[v], v});
		}
	}
	while (!s.empty()) {
		if ((*s.begin()).F == ans) {
			cout << s.size() << endl;
			for (auto it : s)
				cout << it.S << " ";
			cout << endl;
			return 0;
		}
		ans = max (ans, (*s.begin()).F);
		auto v = (*s.begin()).S;
		mark[v] = 0;
		s.erase (s.begin());
		for (auto u : g[v]) {
			if (mark[u] == 2) {
				s.erase ({1. * dinset[u] / d[u], u});
				dinset[u] --;
				s.insert ({1. * dinset[u] / d[u], u});
			}
		}
	}
	cout << ans << endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, k, dg[N], cnt[N];
bool done[N], mark[N];
vector<int> dn, gr[N];
set<pair<double, int> > s;
pair<double, int> mx;
int main() {
	ios_base::sync_with_stdio (false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> k;
	for (int i = 0; i < k; i++) {
		int x;
		cin >> x;
		x--;
		dn.push_back(x), done[x] = 1;
	}
	for (int i = 0; i < m; i++) {
		int x, y;
		cin >> x >> y;
		x--, y--;
		dg[x]++, dg[y]++;
		gr[x].push_back(y), gr[y].push_back(x);
		if (done[x])
			cnt[y]++;
		if (done[y])
			cnt[x]++;
	}
	for (int i = 0; i < n; i++) {
		if (!done[i]) {
			s.insert({(double) (dg[i] - cnt[i]) / (double) dg[i], i});
		}
	}
	while (!s.empty()) {
		auto p = *(s.begin());
		s.erase(s.begin());
		int v = p.second;
//		cout << "p.first= " << p.first << ", " << p.second << endl;
		dn.push_back(v);
		done[v] = 1;
		mx = max(mx, p);
		for (auto u : gr[v]) {
			s.erase({(double) (dg[u] - cnt[u]) / (double) dg[u], u});
			cnt[u]++;
			if (!done[u])
				s.insert({(double) (dg[u] - cnt[u]) / (double) dg[u], u});
		}
	}
	for (auto u : dn) {
		if (u == mx.second)
			break;
		mark[u] = 1;
	}
	vector<int> ans;
	for (int i = 0; i < n; i++)
		if (!mark[i])
			ans.push_back(i + 1);
	cout << ans.size() << "\n";
	for (auto u : ans)
		cout << u << " ";
	return 0;
}


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

const int mx = 1e5+5;
int n, m, k, q[mx];
vector<int> e[mx];
bool fort[mx];

vector<int> check(double r) {
    queue<int> s;
    vector<int> k(n+1, 0);
    vector<bool> in(n+1, false);
    for (int i = 1; i <= n; i++) k[i] = e[i].size(), in[i] = !fort[i];
    for (int i = 1; i <= n; i++) {
        if (fort[i]) continue;
        if ((double)k[i] / (double)q[i] < r) {
            s.push(i);
            in[i] = false;
        }
    }
    while (!s.empty()) {
        int x = s.front(); s.pop();
        for (auto it : e[x]) {
            if (!in[it]) continue;
            if ((double)(--k[it]) / (double)q[it] < r) {
                s.push(it);
                in[it] = false;
            }
        }
    }
    vector<int> ret;
    for (int i = 1; i <= n; i++) {
        if (in[i]) ret.push_back(i);
    }
    return ret;
}

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

    cin >> n >> m >> k;

    for (int i = 1; i <= k; i++) {
        int x; cin >> x;
        fort[x] = true;
    }

    for (int i = 1; i <= m; i++) {
        int x, y; cin >> x >> y;
        q[x]++; q[y]++;
        if (!fort[x] && !fort[y]) {
            e[x].push_back(y);
            e[y].push_back(x);
        }
    }

    double l = 0.0, r = 1.0;
    int count = 50;
    while (count--) {
        double mid = (l+r)/2;
        if (check(mid).size()) l = mid;
        else r = mid;
    }

    vector<int> sol = check(l);

    cout << sol.size() << "\n";
    for (auto it : sol) cout << it << " ";
}


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

const int mx = 1e5+5;
int n, m, k, q[mx];
vector<int> e[mx];
bool fort[mx];

vector<int> check(double r) {
    set<pair<double, int>> s;
    vector<int> k(n+1, 0);
    vector<bool> in(n+1, false);
    for (int i = 1; i <= n; i++) k[i] = e[i].size();
    for (int i = 1; i <= n; i++) {
        if (fort[i]) continue;
        s.insert({(double)k[i] / (double)q[i], i});
        in[i] = true;
    }
    while (!s.empty() && s.begin()->first < r) {
        int x = s.begin()->second;
        for (auto it : e[x]) {
            if (!in[it]) continue;
            s.erase({(double)k[it] / (double)q[it], it});
            s.insert({(double)(--k[it]) / (double)q[it], it});
        }
        s.erase({(double)k[x] / (double)q[x], x});
        in[x] = false;
    }
    vector<int> ret;
    for (int i = 1; i <= n; i++) {
        if (in[i]) ret.push_back(i);
    }
    return ret;
}

int main()
{
    cin >> n >> m >> k;

    for (int i = 1; i <= k; i++) {
        int x; cin >> x;
        fort[x] = true;
    }

    for (int i = 1; i <= m; i++) {
        int x, y; cin >> x >> y;
        q[x]++; q[y]++;
        if (!fort[x] && !fort[y]) {
            e[x].push_back(y);
            e[y].push_back(x);
        }
    }

    double l = 0.0, r = 1.0;
    int count = 100;
    while (count--) {
        double mid = (l+r)/2;
        if (check(mid).size()) l = mid;
        else r = mid;
    }

    vector<int> sol = check(l);

    cout << sol.size() << "\n";
    for (auto it : sol) cout << it << " ";
}


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

const int mx = 1e5+5;
int n, m, k, q[mx];
vector<int> e[mx];
bool fort[mx];

vector<int> check(double r) {
    set<pair<double, int>> s;
    vector<int> k(n+1, 0);
    vector<bool> in(n+1, false);
    for (int i = 1; i <= n; i++) k[i] = e[i].size();
    for (int i = 1; i <= n; i++) {
        if (fort[i]) continue;
        s.insert({(double)k[i] / (double)q[i], i});
        in[i] = true;
    }
    while (!s.empty() && s.begin()->first < r) {
        int x = s.begin()->second;
        for (auto it : e[x]) {
            if (!in[it]) continue;
            s.erase({(double)k[it] / (double)q[it], it});
            s.insert({(double)(--k[it]) / (double)q[it], it});
        }
        s.erase({(double)k[x] / (double)q[x], x});
        in[x] = false;
    }
    vector<int> ret;
    for (int i = 1; i <= n; i++) {
        if (in[i]) ret.push_back(i);
    }
    return ret;
}

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

    cin >> n >> m >> k;

    for (int i = 1; i <= k; i++) {
        int x; cin >> x;
        fort[x] = true;
    }

    for (int i = 1; i <= m; i++) {
        int x, y; cin >> x >> y;
        q[x]++; q[y]++;
        if (!fort[x] && !fort[y]) {
            e[x].push_back(y);
            e[y].push_back(x);
        }
    }

    double l = 0.0, r = 1.0;
    int count = 50;
    while (count--) {
        double mid = (l+r)/2;
        if (check(mid).size()) l = mid;
        else r = mid;
    }

    vector<int> sol = check(l);

    cout << sol.size() << "\n";
    for (auto it : sol) cout << it << " ";
}


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

#define int long long

#define fs first
#define sc second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define fastio ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MP make_pair
#define pb push_back
#define sqr(x) ((x) * (x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 1e5 + 100;
vector<int> g[N];
vector<int> bad, taken(N), used(N);

signed main() {
	fastio;
	#ifdef FlameDragon
		freopen("in.txt", "r", stdin);
		freopen("out.txt", "w", stdout);
	#endif

	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 0; i < k; i++) {
		int x;
		cin >> x;
		x--;
		bad.pb(x);
	}
	for (int i = 0; i < m; i++) {
		int v, u;
		cin >> v >> u;
		v--; u--;
		g[v].pb(u);
		g[u].pb(v);
	}
	double l = 0, r = 1;
	vector<int> ans;
	for (int it = 0; it < 100; it++) {
		double mid = (l + r) / 2;
		for (int i = 0; i < n; i++) {
			taken[i] = sz(g[i]);
		}
		queue<int> q;
		for (auto v : bad) {
			q.push(v);
		}
		while (sz(q)) {
			int v = q.front();
			used[v] = 1;
			q.pop();
			for (auto u : g[v]) {
				taken[u]--;
				if (!used[u] && 1.0 * taken[u] / sz(g[u]) < mid) {
					used[u] = 1;
					q.push(u);
				}
			}
		}
		vector<int> kek;
		for (int i = 0; i < n; i++) {
			if (!used[i]) {
				kek.pb(i);
			}
		}
		if (sz(kek)) {
			l = mid;
			ans = kek;
		} else {
			r = mid;
		}
	}
	assert(sz(ans));
	cout << sz(ans) << '\n';
	for (auto x : ans)
		cout << x + 1 << ' ';
	cout << '\n';
}


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

#define int long long

#define fs first
#define sc second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define fastio ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MP make_pair
#define pb push_back
#define sqr(x) ((x) * (x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define double long double
const int N = 1e5 + 100;
vector<int> g[N];
vector<int> bad, taken(N), used(N);

signed main() {
	fastio;
	#ifdef FlameDragon
		freopen("in.txt", "r", stdin);
		freopen("out.txt", "w", stdout);
	#endif

	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 0; i < k; i++) {
		int x;
		cin >> x;
		x--;
		bad.pb(x);
	}
	for (int i = 0; i < m; i++) {
		int v, u;
		cin >> v >> u;
		v--; u--;
		g[v].pb(u);
		g[u].pb(v);
	}
	const double EPS = 1e-7;
	double l = -EPS, r = 1 + EPS;
	vector<int> ans;
	for (int it = 0; it < 100; it++) {
		double mid = (l + r) / 2;
		for (int i = 0; i < n; i++) {
			taken[i] = sz(g[i]);
			used[i] = 0;
		}
		queue<int> q;
		for (auto v : bad) {
			q.push(v);
		}
		while (sz(q)) {
			int v = q.front();
			used[v] = 1;
			q.pop();
			for (auto u : g[v]) {
				taken[u]--;
				if (!used[u] && 1.0 * taken[u] / sz(g[u]) < mid) {
					used[u] = 1;
					q.push(u);
				}
			}
		}
		vector<int> kek;
		for (int i = 0; i < n; i++) {
			if (!used[i]) {
				kek.pb(i);
			}
		}
		if (sz(kek)) {
			l = mid;
			ans = kek;
		} else {
			r = mid;
		}
	}

	assert(sz(ans));
	cout << sz(ans) << '\n';
	for (auto x : ans)
		cout << x + 1 << ' ';
	cout << '\n';
}


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

#define int long long

#define fs first
#define sc second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define fastio ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MP make_pair
#define pb push_back
#define sqr(x) ((x) * (x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int N = 1e5 + 100;
vector<int> g[N];
vector<int> bad, taken(N), used(N);

signed main() {
	fastio;
	#ifdef FlameDragon
		freopen("in.txt", "r", stdin);
		freopen("out.txt", "w", stdout);
	#endif

	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 0; i < k; i++) {
		int x;
		cin >> x;
		x--;
		bad.pb(x);
	}
	for (int i = 0; i < m; i++) {
		int v, u;
		cin >> v >> u;
		v--; u--;
		g[v].pb(u);
		g[u].pb(v);
	}
	const double EPS = 1e-7;
	double l = -EPS, r = 1;
	vector<int> ans;
	for (int it = 0; it < 100; it++) {
		double mid = (l + r) / 2;
		for (int i = 0; i < n; i++) {
			taken[i] = sz(g[i]);
			used[i] = 0;
		}
		queue<int> q;
		for (auto v : bad) {
			q.push(v);
		}
		while (sz(q)) {
			int v = q.front();
			used[v] = 1;
			q.pop();
			for (auto u : g[v]) {
				taken[u]--;
				if (!used[u] && 1.0 * taken[u] / sz(g[u]) < mid) {
					used[u] = 1;
					q.push(u);
				}
			}
		}
		vector<int> kek;
		for (int i = 0; i < n; i++) {
			if (!used[i]) {
				kek.pb(i);
			}
		}
		if (sz(kek)) {
			l = mid;
			ans = kek;
		} else {
			r = mid;
		}
	}

	assert(sz(ans));
	cout << sz(ans) << '\n';
	for (auto x : ans)
		cout << x + 1 << ' ';
	cout << '\n';
}


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

#define int long long

#define fs first
#define sc second
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define fastio ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MP make_pair
#define pb push_back
#define sqr(x) ((x) * (x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define double long double
const int N = 1e5 + 100;
vector<int> g[N];
vector<int> bad, taken(N), used(N);

signed main() {
	fastio;
	#ifdef FlameDragon
		freopen("in.txt", "r", stdin);
		freopen("out.txt", "w", stdout);
	#endif

	int n, m, k;
	cin >> n >> m >> k;
	for (int i = 0; i < k; i++) {
		int x;
		cin >> x;
		x--;
		bad.pb(x);
	}
	for (int i = 0; i < m; i++) {
		int v, u;
		cin >> v >> u;
		v--; u--;
		g[v].pb(u);
		g[u].pb(v);
	}
	const double EPS = 1e-7;
	double l = -EPS, r = 1 + EPS;
	vector<int> ans;
	for (int it = 0; it < 100; it++) {
		double mid = (l + r) / 2;
		for (int i = 0; i < n; i++) {
			taken[i] = sz(g[i]);
			used[i] = 0;
		}
		queue<int> q;
		for (auto v : bad) {
			q.push(v);
			used[v] = 1;
		}
		while (sz(q)) {
			int v = q.front();
			used[v] = 1;
			q.pop();
			for (auto u : g[v]) {
				taken[u]--;
				if (!used[u] && 1.0 * taken[u] / sz(g[u]) < mid) {
					used[u] = 1;
					q.push(u);
				}
			}
		}
		vector<int> kek;
		for (int i = 0; i < n; i++) {
			if (!used[i]) {
				kek.pb(i);
			}
		}
		if (sz(kek)) {
			l = mid;
			ans = kek;
		} else {
			r = mid;
		}
	}

	assert(sz(ans));
	cout << sz(ans) << '\n';
	for (auto x : ans)
		cout << x + 1 << ' ';
	cout << '\n';
}


#include <bits/stdc++.h>

using namespace std;

const int MAX = 1e5 + 10;
const long long BASE = 1e12;

vector<vector<int>> G(MAX);

bool bfs (long long val, vector<int> dark, vector<int>& ans) {
  int n = dark.size();
  vector<pair<long long, long long>> ratio(n);
  queue<int> q;
  for (int i = 0; i < n; i++) {
    ratio[i].first = ratio[i].second = G[i].size();
    if (dark[i]) {
      q.push(i);
    }
  }
  while (!q.empty()) {
    int nd = q.front();
    q.pop();
    for (int nxt : G[nd]) {
      if (!dark[nxt]) {
        ratio[nxt].first--;
      }
    }
    for (int nxt : G[nd]) {
      if (!dark[nxt]) {
        long long scale = (ratio[nxt].first * BASE + ratio[nxt].second - 1) / ratio[nxt].second;
        if (scale < val) {
          dark[nxt] = 1;
          q.push(nxt);
        }
      }
    }
  }
  int count = 0;
  for (int i = 0; i < n; i++) {
    if (!dark[i]) {
      ans.push_back(i);
      count++;
    }
  }
  return count;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m, k;
  cin >> n >> m >> k;
  vector<int> dark(n);
  for (int i = 0; i < k; i++) {
    int x;
    cin >> x;
    x--;
    dark[x] = 1;
  }
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  long long l = 0, r = BASE;
  vector<int> ans;
  while (l != r) {
    long long mid = (l + r + 1) / 2;
    vector<int> nans;
    bool ok = bfs(mid, dark, nans);
    if (ok) {
      ans = nans;
      l = mid;
    } else {
      r = mid - 1;
    }
  }
  if (l == 0) {
    bfs(0, dark, ans);
  }
  cout << (int) ans.size() << '\n';
  for (int i = 0; i < (int) ans.size(); i++) {
    cout << ans[i] + 1 << ' ';
  }
  cout << '\n';
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

template <typename T>
void debug_out(T t) {
  cerr << t;
}

template <typename A, typename B>
void debug_out(pair<A, B> u) {
  cerr << "(" << u.first << " " << u.second << ")";
}

template <typename T>
void debug_out(vector<T> t) {
  int sz = t.size();
  for(int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if(i != sz - 1) cerr << ", ";
  }
}

template <typename T>
void debug_out(vector<vector<T>> t) {
  int sz = t.size();
  for(int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if(i != sz - 1) cerr << endl;
  }
}

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  debug_out(H);
  cerr << " ";
  debug_out(T...);
}

template <typename T>
void debug_out(set<T> a) {
  vector<T> _a;
  for(T t : a) _a.push_back(t);
  debug_out(_a);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__), cerr << endl;

int n, m, k;

int main() {
  cin >> n >> m >> k;
  vector<vector<int>> g(n);
  set<int> fort;
  range(i, 0, k) {
    int a;
    cin >> a;
    a--;
    fort.insert(a);
  }
  vector<int> deg(n);
  vector<int> port(n);
  range(i, 0, m) {
    int a, b;
    cin >> a >> b;
    a--; b--;
    g[a].push_back(b);
    g[b].push_back(a);
    deg[a]++; deg[b]++;
    port[a] += fort.find(b) == fort.end();
    port[b] += fort.find(a) == fort.end();
  }
  vector<pair<int, int>> seg;
  range(i, 0, n) {
    range(j, 0, deg[i] + 1) seg.emplace_back(j, deg[i]);
  }
  sort(seg.begin(), seg.end(), [&](pair<int, int> a, pair<int, int> b) {
    return 1LL * a.first * b.second < 1LL * b.first * a.second;
  });
  auto solve = [&](int id) {
    vector<int> que;
    vector<int> was(n);
    for(int i : fort) {
      que.push_back(i);
      was[i] = 1;
    }
    vector<int> cur = deg;
    for(int b = 0; b < (int) que.size(); b++) {
      for(int i : g[que[b]]) {
        cur[i]--;
        if(was[i] == 0 && 1LL * cur[i] * seg[id].second < 1LL * seg[id].first * deg[i]) {
          que.push_back(i);
          was[i] = 1;
        }
      }
    }
    return was;
  };
  int lo = 0, hi = seg.size();
  while(hi - lo > 1) {
    int mid = (hi + lo) >> 1;
    vector<int> ret = solve(mid);
    if(*min_element(ret.begin(), ret.end()) == 1) hi = mid;
    else lo = mid;
  }
  vector<int> ret = solve(lo);
  vector<int> res;
  range(i, 0, n) if(!ret[i]) res.push_back(i);
  cout << res.size() << endl;
  for(int i : res) cout << i + 1 << " ";
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

int n, m, k;

int main() {
  cin >> n >> m >> k;
  vector<vector<int>> g(n);
  set<int> fort;
  range(i, 0, k) {
    int a;
    cin >> a;
    a--;
    fort.insert(a);
  }
  vector<int> deg(n);
  vector<int> port(n);
  range(i, 0, m) {
    int a, b;
    cin >> a >> b;
    a--; b--;
    g[a].push_back(b);
    g[b].push_back(a);
    deg[a]++; deg[b]++;
    port[a] += fort.find(b) == fort.end();
    port[b] += fort.find(a) == fort.end();
  }
  vector<pair<int, int>> seg;
  range(i, 0, n) {
    seg.emplace_back(port[i], deg[i]);
  }
  sort(seg.begin(), seg.end(), [&](pair<int, int> a, pair<int, int> b) {
    return 1LL * a.first * b.second < 1LL * b.first * a.second;
  });
  auto solve = [&](int id) {
    vector<int> que;
    vector<int> was(n);
    for(int i : fort) {
      que.push_back(i);
      was[i] = 1;
    }
    vector<int> cur = deg;
    for(int b = 0; b < (int) que.size(); b++) {
      for(int i : g[que[b]]) {
        cur[i]--;
        if(was[i] == 0 && 1LL * cur[i] * seg[id].second < 1LL * seg[id].first * deg[i]) {
          que.push_back(i);
          was[i] = 1;
        }
      }
    }
    return was;
  };
  int lo = 0, hi = n;
  while(hi - lo > 1) {
    int mid = (hi + lo) >> 1;
    vector<int> ret = solve(mid);
    if(*min_element(ret.begin(), ret.end()) == 1) hi = mid;
    else lo = mid;
  }
  vector<int> ret = solve(lo);
  vector<int> res;
  range(i, 0, n) if(!ret[i]) res.push_back(i);
  cout << res.size() << endl;
  for(int i : res) cout << i + 1 << " ";
  return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define repi(i, a, b) for(int i=(a); i>(b); i--)
#define db(x) (cerr << #x << ": " << (x) << '\n')
#define sync ios_base::sync_with_stdio(false), cin.tie(NULL)
#define cps CLOCKS_PER_SEC
#define tests(t) int t; cin >> t; while(t--)
#define iceil(n, x) (((n) + (x) - 1) / (x))
#define ll long long
#define gcd __gcd
#define eb emplace_back
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define sz size()
#define all(v) (v).begin(), (v).end()
#define uni(v) sort(all(v)), (v).erase(unique(all(v)), (v).end())
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define fi first
#define se second
#define mt make_tuple
#define pqueue priority_queue
#define bitcount(x) __builtin_popcount(x)
#define PI acos(-1.0)
#define EPS 1e-9
#define mod 1000000007
using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}

template<typename T1, typename T2>
ostream& operator << (ostream& os, const pair<T1, T2>& p) { return os << '(' << p.fi << ", " << p.se << ')'; }

template<typename T>
void printv(const T& v) { for(auto i : v) cerr << i << ' '; cerr << '\n'; }

template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

template<typename T>
using maxpq = priority_queue<T>;

//All indexing is 0-based
using namespace __gnu_pbds;
template<class key, class cmp = std::less<key>>
using ordered_set = tree<key, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
//methods: find_by_order(k); & order_of_key(k);
//To make it an ordered_multiset, use pairs of (value, time_of_insertion)
//to distinguish values which are similar

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;

//Returns no. of values x for which ceil(n / x) == y (y must be > 1).
inline ll CC(ll n, ll y) { return iceil(n, y-1) - iceil(n, y); }

//Returns no. of values x for which floor(n / x) == y
inline ll FF(ll n, ll y) { return n / y - n / (y+1); }

//a and b are assumed to be taken modulo p
inline int add(int a, int b, int p = mod){ int c = a + b; if(c >= p) c -= p; return c; }
inline int sub(int a, int b, int p = mod){ int c = a - b; if(c < 0) c += p; return c; }
inline int mul(int a, int b, int p = mod){ return (a * 1ll * b) % p; }

#define N 100005
#define int ll
// #define trace(...) 42

int n, m, k;
bool fort[N];
bool has[N];
vi adj[N];

#define ppii pair<pii, int>

struct comp {
    bool operator() (ppii p, ppii q) const {
        int val_l = p.fi.fi * q.fi.se;
        int val_r = p.fi.se * q.fi.fi;
        if(val_l != val_r) return val_l < val_r;
        return p.se < q.se;
    }
};

set<pair<pii, int>, comp> rem;
int num[N], den[N];

double mx = 0;

void solve(bool print) {

    for(int i = 0; i < n; i++) {
        if(!fort[i]) {
            int num, den;
            num = den = 0;
            for(int j : adj[i]) {
                ++den;
                num += !fort[j];
            }
            rem.insert({{num, den}, i});
            ::num[i] = num, ::den[i] = den;
            has[i] = 1;
        }
    }

    while(rem.size()) {
        auto p = *rem.begin();

        int i = p.se;
        double val = num[i] * 1. / den[i];

        // trace(rem.size(), i, val);

        if(print && abs(mx - val) < EPS) {
            cout << rem.size() << '\n';
            for(auto p : rem) {
                cout << p.se + 1 << ' ';
            }
            return;
        }

        rem.erase(p);
        mx = max(mx, val);

        for(int j : adj[i]) {
            if(has[j]) {
                rem.erase({{num[j], den[j]}, j});
                --num[j];
                rem.insert({{num[j], den[j]}, j});
            }
        }

        has[i] = 0;
    }
    rem.clear();
}

main()
{
    #ifndef ONLINE_JUDGE
        freopen("/home/tarun/Desktop/input.txt", "r", stdin);
     // freopen("/home/tarun/Desktop/output.txt", "w", stdout);
    #endif
    sync;
    clock_t clk = clock();
    cerr << "I will return...\n";

    cin >> n >> m >> k;

    rep(i, 0, k) {
        int j; cin >> j; --j; fort[j] = 1;
    }

    rep(i, 0, m) {
        int u, v; cin >> u >> v;
        --u, --v;
        adj[u].pb(v);
        adj[v].pb(u);
    }

    solve(0);
    solve(1);

    cerr << "...don't you ever hang your head.\n";
    cerr << "Time (in ms): " << (double)(clock() - clk) * 1000.0 / cps << '\n';
}

//Compile using:
//g++ -o filename.exe --std=c++11 filename.cpp
//Use -D CP for defining a macro CP in the local environment


/*⠄⢰⣧⣼⣯⠄⣸⣠⣶⣶⣦⣾⠄⠄⠄⠄⡀⠄⢀⣿⣿⠄⠄⠄⢸⡇⠄⠄
⠄⠄⠄⣾⣿⠿⠿⠶⠿⢿⣿⣿⣿⣿⣦⣤⣄⢀⡅⢠⣾⣛⡉⠄⠄⠄⠸⢀⣿⠄
⠄⠄⢀⡋⣡⣴⣶⣶⡀⠄⠄⠙⢿⣿⣿⣿⣿⣿⣴⣿⣿⣿⢃⣤⣄⣀⣥⣿⣿⠄
⠄⠄⢸⣇⠻⣿⣿⣿⣧⣀⢀⣠⡌⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⣿⣿⣿⠄
⠄⢀⢸⣿⣷⣤⣤⣤⣬⣙⣛⢿⣿⣿⣿⣿⣿⣿⡿⣿⣿⡍⠄⠄⢀⣤⣄⠉⠋⣰
⠄⣼⣖⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⢇⣿⣿⡷⠶⠶⢿⣿⣿⠇⢀⣤
⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣷⣶⣥⣴⣿⡗
⢀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠄
⢸⣿⣦⣌⣛⣻⣿⣿⣧⠙⠛⠛⡭⠅⠒⠦⠭⣭⡻⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠄
⠘⣿⣿⣿⣿⣿⣿⣿⣿⡆⠄⠄⠄⠄⠄⠄⠄⠄⠹⠈⢋⣽⣿⣿⣿⣿⣵⣾⠃⠄
⠄⠘⣿⣿⣿⣿⣿⣿⣿⣿⠄⣴⣿⣶⣄⠄⣴⣶⠄⢀⣾⣿⣿⣿⣿⣿⣿⠃⠄⠄
⠄⠄⠈⠻⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⣿⠄⣿⣿⡀⣾⣿⣿⣿⣿⣛⠛⠁⠄⠄⠄
⠄⠄⠄⠄⠈⠛⢿⣿⣿⣿⠁⠞⢿⣿⣿⡄⢿⣿⡇⣸⣿⣿⠿⠛⠁⠄⠄⠄⠄⠄
⠄⠄⠄⠄⠄⠄⠄⠉⠻⣿⣿⣾⣦⡙⠻⣷⣾⣿⠃⠿⠋⠁⠄⠄⠄⠄⠄⢀⣠⣴
⣿⣿⣿⣶⣶⣮⣥⣒⠲⢮⣝⡿⣿⣿⡆⣿⡿⠃⠄⠄⠄⠄⠄⠄⠄⣠⣴⣿*/

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define ll long long
#define ii pair<ll,ll>
#define iii pair<ii,ll>
#define fi first
#define se second
#define endl '\n'
#define debug(x) cout << #x << " is " << x << endl;

#define rep(x,start,end) for(auto x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()

ll MAX(ll a){return a;}
ll MIN(ll a){return a;}
template<typename... Args>
ll MAX(ll a,Args... args){return max(a,MAX(args...));}
template<typename... Args>
ll MIN(ll a,Args... args){return min(a,MIN(args...));}

#define indexed_set tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>

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

#define di pair<double,int>

int n,m,k;
bool block[100005];

vector<int> al[100005];
bool vis[100005];
int dg[100005];
int active[100005];

priority_queue<di,vector<di>,greater<di> > pq;
set<int> proc;

double calc(int i){
	return (double)active[i]/dg[i];
}

void dfs(int i){
	vis[i]=true;

	for (auto &it:al[i]){
		dg[i]++;
		if (!block[it]) active[i]++;
		if (!block[it] && !vis[it]) dfs(it);
	}

	pq.push(di(calc(i),i));
	proc.insert(i);
}

double best=-1;
vector<int> ans;

void get_ans(int i){
	ans.push_back(i);

	vis[i]=true;

	for (auto &it:al[i]){
		if (proc.count(it) && !vis[it]) get_ans(it);
	}
}

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

	cin>>n>>m>>k;

	rep(x,0,k){
		int t;
		cin>>t;
		block[t]=true;
	}

	rep(x,0,m){
		int a,b;
		cin>>a>>b;
		al[a].push_back(b);
		al[b].push_back(a);
	}

	rep(x,1,n+1) if (!block[x] && !vis[x]){
		while (!pq.empty()) pq.pop();
		proc.clear();
		dfs(x);

		double weight;
		int node;
		while (!pq.empty()){
			weight=pq.top().fi;
			node=pq.top().se;
			pq.pop();

			if (weight!=calc(node)) continue;

			best=max(best,weight);

			for (auto &it:al[node]){
				if (proc.count(it)){
					active[it]--;

					pq.push(di(calc(it),it));
				}
			}

			proc.erase(node);
		}
	}

	//cout<<best<<endl;

	memset(dg,0,sizeof(dg));
	memset(active,0,sizeof(active));
	memset(vis,false,sizeof(vis));

	rep(x,1,n+1) if (!block[x] && !vis[x]){
		while (!pq.empty()) pq.pop();
		proc.clear();
		dfs(x);

		double weight;
		int node;
		while (!pq.empty()){
			weight=pq.top().fi;
			node=pq.top().se;
			pq.pop();

			if (weight!=calc(node)) continue;

			if (weight==best){
				memset(vis,false,sizeof(vis));
				get_ans(node);

				cout<<sz(ans)<<endl;
				for (auto &it:ans) cout<<it<<" ";

				return 0;
			}

			for (auto &it:al[node]){
				if (proc.count(it)){
					active[it]--;

					pq.push(di(calc(it),it));
				}
			}

			proc.erase(node);
		}
	}
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return (adj[v] * 1.0) / (deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }
	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         }
	 }

	 for (i = 1; i <= n; i++) {
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         ans[cnt++] = i;
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	for (i = 0 ; i < 80; i++) {
		double mid = low + (high - low) / 2.0;
		if (valid(mid)) {
		   low = mid;
		} else {
  		   high = mid;
		}
	}

	printf("%d\n", cnt);
	for (i = 0 ; i < cnt; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt, tol = 0;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return ((double) adj[v] * 1.0) / ((double) deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }

	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         } else {
             del[i] = true;
         }
	 }

	 for (i = 1; i <= n; i++) {
	     adj[i] = adj[i] / 2;
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         cnt++;
	         break;
	     }
	 }

	 if (cnt > 0) {
	     tol = 0;
	     for (i = 1; i <= n; i++) {
	         if (!del[i]) {
	             ans[tol++] = i;
	         }
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 2.00;
	double ret = 0.00;
	for (i = 0 ; i < 30; i++) {
		double mid = (low + high) / 2.0;
		if (valid(mid)) {
		   low = mid;
		   ret = mid;
		} else {
  		   high = mid;
		}
	}

	valid(ret);
	printf("%d\n", tol);
	for (i = 0 ; i < tol; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt, tol = 0;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return ((double) adj[v] * 1.0) / ((double) deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }

	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         } else {
             del[i] = true;
         }
	 }

	 for (i = 1; i <= n; i++) {
	     adj[i] = adj[i] / 2;
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         cnt++;
	         break;
	     }
	 }

	 if (cnt > 0) {
	     tol = 0;
	     for (i = 1; i <= n; i++) {
	         if (!del[i]) {
	             ans[tol++] = i;
	         }
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	double ret = 0.00;
	for (i = 0 ; i < 80; i++) {
		double mid = (low + high) / 2.0;
		if (valid(mid)) {
		   low = mid;
		   ret = mid;
		} else {
  		   high = mid;
		}
	}

	valid(ret);
	printf("%d\n", tol);
	for (i = 0 ; i < tol; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt, tol = 0;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return ((double) adj[v] * 1.0) / ((double) deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }

	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         }
	 }

	 for (i = 1; i <= n; i++) {
	     adj[i] = adj[i] / 2;
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         cnt++;
	         break;
	     }
	 }

	 if (cnt > 0) {
	     tol = 0;
	     for (i = 1; i <= n; i++) {
	         if (!del[i]) {
	             ans[tol++] = i;
	         }
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		del[v] = true;
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	double ret = 0.00;
	for (i = 0 ; i < 80; i++) {
		double mid = (low + high) / 2.0;
		if (valid(mid)) {
		   low = mid;
		   ret = mid;
		} else {
  		   high = mid;
		}
	}

	valid(ret);
	printf("%d\n", tol);
	for (i = 0 ; i < tol; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return (adj[v] * 1.0) / (deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }
	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         }
	 }

	 for (i = 1; i <= n; i++) {
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         ans[cnt++] = i;
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	for (i = 0 ; i < 100; i++) {
		double mid = low + (high - low) / 2.0;
		if (valid(mid)) {
		   low = mid;
		} else {
  		   high = mid;
		}
	}

	printf("%d\n", cnt);
	for (i = 0 ; i < cnt; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt, tol = 0;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return ((double) adj[v] * 1.0) / ((double) deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }

	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         } else {
             del[i] = true;
         }
	 }

	 for (i = 1; i <= n; i++) {
	     adj[i] = adj[i] / 2;
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         cnt++;
	         break;
	     }
	 }

	 if (cnt > 0) {
	     tol = 0;
	     for (i = 1; i <= n; i++) {
	         if (!del[i]) {
	             ans[tol++] = i;
	         }
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	double ret = 0.00;
	for (i = 0 ; i < 60; i++) {
		double mid = (low + high) / 2.0;
		if (valid(mid)) {
		   low = mid;
		   ret = mid;
		} else {
  		   high = mid;
		}
	}

	valid(ret);
	printf("%d\n", tol);
	for (i = 0 ; i < tol; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt, tol = 0;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return ((double) adj[v] * 1.0) / ((double) deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }

	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         }
	 }

	 for (i = 1; i <= n; i++) {
	     adj[i] = adj[i] / 2;
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         cnt++;
	         break;
	     }
	 }

	 if (cnt > 0) {
	     tol = 0;
	     for (i = 1; i <= n; i++) {
	         if (!del[i]) {
	             ans[tol++] = i;
	         }
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1e5;
	double ret = 0.00;
	for (i = 0 ; i < 80; i++) {
		double mid = (low + high) / 2.0;
		if (valid(mid)) {
		   low = mid;
		   ret = mid;
		} else {
  		   high = mid;
		}
	}

	valid(ret);
	printf("%d\n", tol);
	for (i = 0 ; i < tol; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define MOD 1000000007
#define MAX_SIZE 100011
typedef long long ll;
using namespace std;

bool frt[MAX_SIZE];
vector<int> g[MAX_SIZE];
unordered_set<int> h[MAX_SIZE];
int n, m, k;
int deg[MAX_SIZE], adj[MAX_SIZE];
int cnt;
int ans[MAX_SIZE];
bool del[MAX_SIZE];

double score(int v) {
    return (adj[v] * 1.0) / (deg[v] * 1.0);
}

bool valid(double mid) {
	 int i;
	 cnt = 0;
	 for (i = 0 ; i <= n; i++) {
	     del[i] = false;
	     h[i].clear();
	     adj[i] = 0;
	 }
	 queue<int> q;
	 for (i = 1; i <= n; i++) {
	 	 if (!frt[i]) {
		  	for (auto v : g[i]) {
				if (!frt[v]) {
				   h[v].insert(i), h[i].insert(v);
				   adj[v]++, adj[i]++;
				}
		    }
         }
	 }

	 for (i = 1; i <= n; i++) {
	     if (score(i) < mid) {
	         q.push(i);
	     }
	 }

	 while (!q.empty()) {
	     int v = q.front();
	     q.pop();
	     if (del[v]) continue;
	     del[v] = true;
	     adj[v] = 0;
	     for (auto nv : h[v]) {
	         if (!del[nv]) {
	             adj[nv]--;
	             if (score(nv) < mid) {
	                 q.push(nv);
	             }
	         }
	     }
	     h[v].clear();
	 }

	 for (i = 1; i <= n; i++) {
	     if (!del[i]) {
	         ans[cnt++] = i;
	     }
	 }

	 return cnt > 0;
}

int main(){
	scanf("%d%d%d", &n, &m, &k);
	int i;
	for (i = 0; i < k; i++) {
		int v;
		scanf("%d", &v);
		frt[v] = true;
	}

	for (i = 0 ; i < m; i++) {
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		g[v1].push_back(v2), g[v2].push_back(v1);
		deg[v1]++, deg[v2]++;
	}

	double low = 0.0, high = 1.00;
	for (i = 0 ; i < 100; i++) {
		double mid = low + (high - low) / 2.0;
		if (valid(mid)) {
		   low = mid;
		} else {
  		   high = mid;
		}
	}

	printf("%d\n", cnt);
	for (i = 0 ; i < cnt; i++) {
		printf("%d ", ans[i]);
	}
	printf("\n");
	return 0;
}


// https://codeforces.com/blog/entry/18842?#comment-237922

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

#define int long long
#define ld long double
// #define db double
#define endl "\n"
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define RAND mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()
#define debx cout << " X " << endl;
#define deby cout << " Y " << endl;
#define debz cout << " Z " << endl;
#define deb(x) cout << '>' << #x << ':' << x << endl;

const long double PI = 3.14159265358979323846264338;
const long long INF = 1000000000000000000;
const long long INF1 = 1000000000;
const long long MOD = 1000000007;
// const long long MOD = 998244353;

using namespace __gnu_pbds;
using namespace std;
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
/*
    find_by_order() - Returns an iterator to the k-th largest element (counting from zero)
    order_of_key()  - The number of items in a set that are strictly smaller than our item
    Rest same as set
*/

int mpow(int a, int b){
    a %= MOD;
    if(!b)
        return 1;
    int temp = mpow(a, b / 2);
    temp = (temp * temp) % MOD;
    if(b % 2)
        return (a * temp) % MOD;
    return temp;
}
int _pow(int a, int b){
    if(!b)
        return 1;
    int temp = _pow(a, b / 2);
    temp = (temp * temp);
    if(b % 2)
        return (a * temp);
    return temp;
}
int mod_in(int n){
    return mpow(n, MOD - 2);
}
int cl(int a, int b){
    if(a % b)
        return 1 + a / b;
    return a / b;
}

const int N = 1e5 + 5;
int n, m, k, itr = 100, check[N] = {0}, ans[N] = {0};
vector<int> adj[N];

bool solve(double r){
    queue<int> Q;
    int size[n + 5] = {0}, rem = 0;
    for(int i = 1 ; i <= n ; i++){
        if(check[i]){
            ans[i] = 0;
            Q.push(i);
            rem++;
        }
        else{
            ans[i] = 1;
            for(auto v : adj[i])
                size[v]++;
        }
    }
    while(!Q.empty()){
        int top = Q.front();
        Q.pop();
        for(auto v : adj[top]){
            if(ans[v] && (double) size[v] / (double) adj[v].size() < r){
                for(auto k : adj[v])
                    size[k]--;
                Q.push(v);
                ans[v] = 0;
                rem++;
            }
        }
    }
    return rem != n;
}

int32_t main(){
    fastio;
    cin >> n >> m >> k;
    for(int i = 0 ; i < k ; i++){
        int id;
        cin >> id;
        check[id] = 1;
    }
    for(int i = 0 ; i < m ; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    double lo = 0, hi = 1;
    int fans[n + 5] = {0}, ct = 0;
    while(itr--){
        double mid = (double) (lo + hi) / 2;
        if(solve(mid)){
            ct = 0;
            for(int i = 1 ; i <= n ; i++){
                fans[i] = ans[i];
                ct += fans[i];
            }
            lo = mid;
        }
        else
            hi = mid;
    }
    if(ct == 0){
        for(int i = 1 ; i <= n ; i++)
            if(check[i] == 0){
                fans[i] = 1;
                ct++;
            }
    }
    cout << ct << endl;
    for(int i = 1 ; i <= n ; i++)
        if(fans[i])
            cout << i << " ";
}


// https://codeforces.com/blog/entry/18842?#comment-237922

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

#define int long long
#define ld long double
// #define db double
#define endl "\n"
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define RAND mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()
#define debx cout << " X " << endl;
#define deby cout << " Y " << endl;
#define debz cout << " Z " << endl;
#define deb(x) cout << '>' << #x << ':' << x << endl;

const long double PI = 3.14159265358979323846264338;
const long long INF = 1000000000000000000;
const long long INF1 = 1000000000;
const long long MOD = 1000000007;
// const long long MOD = 998244353;

using namespace __gnu_pbds;
using namespace std;
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
/*
    find_by_order() - Returns an iterator to the k-th largest element (counting from zero)
    order_of_key()  - The number of items in a set that are strictly smaller than our item
    Rest same as set
*/

int mpow(int a, int b){
    a %= MOD;
    if(!b)
        return 1;
    int temp = mpow(a, b / 2);
    temp = (temp * temp) % MOD;
    if(b % 2)
        return (a * temp) % MOD;
    return temp;
}
int _pow(int a, int b){
    if(!b)
        return 1;
    int temp = _pow(a, b / 2);
    temp = (temp * temp);
    if(b % 2)
        return (a * temp);
    return temp;
}
int mod_in(int n){
    return mpow(n, MOD - 2);
}
int cl(int a, int b){
    if(a % b)
        return 1 + a / b;
    return a / b;
}

const int N = 1e5 + 5;
int n, m, k, itr = 100, check[N] = {0}, ans[N] = {0};
vector<int> adj[N];

bool solve(double r){
    queue<int> Q;
    int size[n + 5] = {0}, rem = 0;
    for(int i = 1 ; i <= n ; i++){
        if(check[i]){
            ans[i] = 0;
            Q.push(i);
            rem++;
        }
        else{
            ans[i] = 1;
            for(auto v : adj[i])
                size[v]++;
        }
    }
    while(!Q.empty()){
        int top = Q.front();
        Q.pop();
        for(auto v : adj[top]){
            if(ans[v] && (double) size[v] / (double) adj[v].size() < r){
                for(auto k : adj[v])
                    size[k]--;
                Q.push(v);
                ans[v] = 0;
                rem++;
            }
        }
    }
    return rem != n;
}

int32_t main(){
    cin >> n >> m >> k;
    for(int i = 0 ; i < k ; i++){
        int id;
        cin >> id;
        check[id] = 1;
    }
    for(int i = 0 ; i < m ; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    double lo = 0, hi = 1;
    int fans[n + 5] = {0}, ct = 0;
    while(itr--){
        double mid = (double) (lo + hi) / 2;
        if(solve(mid)){
            ct = 0;
            for(int i = 1 ; i <= n ; i++){
                fans[i] = ans[i];
                ct += fans[i];
            }
            lo = mid;
        }
        else
            hi = mid;
    }
    if(ct == 0){
        for(int i = 1 ; i <= n ; i++)
            if(check[i] == 0){
                fans[i] = 1;
                ct++;
            }
    }
    cout << ct << endl;
    for(int i = 1 ; i <= n ; i++)
        if(fans[i])
            cout << i << " ";
}


// https://codeforces.com/blog/entry/18842?#comment-237922

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

#define int long long
#define ld long double
// #define db double
#define endl "\n"
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define RAND mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()
#define debx cout << " X " << endl;
#define deby cout << " Y " << endl;
#define debz cout << " Z " << endl;
#define deb(x) cout << '>' << #x << ':' << x << endl;

const long double PI = 3.14159265358979323846264338;
const long long INF = 1000000000000000000;
const long long INF1 = 1000000000;
const long long MOD = 1000000007;
// const long long MOD = 998244353;

using namespace __gnu_pbds;
using namespace std;
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
/*
    find_by_order() - Returns an iterator to the k-th largest element (counting from zero)
    order_of_key()  - The number of items in a set that are strictly smaller than our item
    Rest same as set
*/

int mpow(int a, int b){
    a %= MOD;
    if(!b)
        return 1;
    int temp = mpow(a, b / 2);
    temp = (temp * temp) % MOD;
    if(b % 2)
        return (a * temp) % MOD;
    return temp;
}
int _pow(int a, int b){
    if(!b)
        return 1;
    int temp = _pow(a, b / 2);
    temp = (temp * temp);
    if(b % 2)
        return (a * temp);
    return temp;
}
int mod_in(int n){
    return mpow(n, MOD - 2);
}
int cl(int a, int b){
    if(a % b)
        return 1 + a / b;
    return a / b;
}

const int N = 1e5 + 5;
int n, m, k, itr = 100, check[N] = {0}, ans[N] = {0};
vector<int> adj[N];

bool solve(double r){
    queue<int> Q;
    int size[n + 5] = {0}, rem = 0;
    for(int i = 1 ; i <= n ; i++){
        if(check[i]){
            ans[i] = 0;
            Q.push(i);
            rem++;
        }
        else{
            ans[i] = 1;
            for(auto v : adj[i])
                size[v]++;
        }
    }
    while(!Q.empty()){
        int top = Q.front();
        Q.pop();
        for(auto v : adj[top]){
            if(ans[v] && (double) size[v] / (double) adj[v].size() < r){
                for(auto k : adj[v])
                    size[k]--;
                Q.push(v);
                ans[v] = 0;
                rem++;
            }
        }
    }
    return rem != n;
}

int32_t main(){
    cin >> n >> m >> k;
    for(int i = 0 ; i < k ; i++){
        int id;
        cin >> id;
        check[id] = 1;
    }
    for(int i = 0 ; i < m ; i++){
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    double lo = 0, hi = 1;
    int fans[n + 5] = {0}, ct = 0;
    while(itr--){
        double mid = (double) (lo + hi) / 2;
        if(solve(mid)){
            ct = 0;
            for(int i = 1 ; i <= n ; i++){
                fans[i] = ans[i];
                ct += fans[i];
            }
            lo = mid;
        }
        else
            hi = mid;
    }
    cout << ct << endl;
    for(int i = 1 ; i <= n ; i++)
        if(fans[i])
            cout << i << " ";
}


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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define FOR(i,j,k,in) for(int i=(j); i < (k);i+=in)
#define FORD(i,j,k,in) for(int i=(j); i >=(k);i-=in)
#define REP(i,b) FOR(i,0,b,1)
#define REPD(i,b) FORD(i,b,0,1)
#define pb push_back
#define mp make_pair
#define INF (int)1e9
#define MINF -(int)1e9
#define EPS 1e-9
#define MOD 1000000007
#define MOD2 998244353
#define PI 3.1415926535
#define ff first
#define ss second

#ifdef DEBUG
#define DBG if(1)
#else
#define DBG if(0)
#endif

#define dbg(x) cout << "(" << #x << " : " << x << ")" << endl;

template <class T, class U>
ostream& operator<<(ostream& out, const pair<T, U> &par) {
    out << "[" << par.first << ";" << par.second << "]";
    return out;
}

template <class T>
ostream& operator<<(ostream& out, const set<T> &cont) {
    out << "{";
    for( const auto &x:cont) out << x << ", ";
    out << "}";
    return out;
}

template <class T, class U>
ostream& operator<<(ostream& out, const map<T, U> &cont) {
    out << "{";
    for( const auto &x:cont) out << x << ", ";
    out << "}";
    return out;
}

template<class T>
ostream& operator<<(ostream& out, const vector<T> &v){
    out << "[";
    REP(i, v.size()) out << v[i] << ", ";
    out << "]";
    return out;
}
class edge{
    public:
        int src, dest;
        ll w;
        edge(int from, int to, ll weight){
            src = from;
            dest = to;
            w = weight;
        }
    };
class undigraph{
    public:
        int n;
        vector<edge> edges;
        vector<vi> adj;
        undigraph(int n){
            this->n = n;
            adj.resize(n);
        }
        void add_edge(int u, int v, ll w){
            edges.pb(edge(u, v, w));
            int id = edges.size()-1;
            adj[u].pb(id);
            adj[v].pb(id);
        }
    };
vector<bool> bad;
bool check(double x, undigraph &g, vi &ans, bool construct){
    // nejake menim na fortressy
    vector<bool> fortress = bad;
    queue<int> q;
    REP(i, g.n) {
        if (fortress[i]) continue;
        int good = 0;
        for (auto id : g.adj[i]) {
            edge e = g.edges[id];
            int other = i ^ e.src ^e.dest;
            if (!fortress[other]) good++;
        }
        if ((double) good / (double) g.adj[i].size() < x) q.push(i); // theoretically add EPS, cause doubles suck
    }
    while(!q.empty()){
        int v = q.front();
        q.pop();
        int good = 0;
        for(auto id : g.adj[v]){
            edge e = g.edges[id];
            int other = e.src ^ e.dest ^ v;
            if(!fortress[other]) good++;
        }
        if((double) good / (double) g.adj[v].size() < x){
            fortress[v] = true;
            for(auto id : g.adj[v]){
                edge e = g.edges[id];
                int other = e.src ^ e.dest ^ v;
                if(!fortress[other]) q.push(other);
            }
        }
    }
    if(!construct){
        bool can = false;
        REP(i, g.n){
            if(!fortress[i]) can = true;
        }
        return can;
    }
    else{
        REP(i, g.n){
            if(!fortress[i]) ans.pb(i);
        }
        return true;
    }
}
vector<double> possible_fractions;
double solve(undigraph &g){
    int l = 0;
    int r = 1;
    int cnt = 0;
    vi temp;
    double ans = 0;
    while(l<=r){
        int m = (l+r)/2;
        if(check(possible_fractions[m], g, temp, false)){
            l = m + 1;
            ans = possible_fractions[m];
        }
        else r = m-1;
    }
    return ans;
}
// ocividne wa alebo tle ak zmenim cnt limit
// skusime ist cez vsetky mozne zlomky -> pre kazdy vrchol, pridam do setu vsetky x / pocet susedov
// takychto zlomkov tam bude radovo m
// snad to bude AC :)
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    int n,m,k; cin >> n >> m >> k;
    bad.resize(n);
    undigraph g(n);
    REP(i, k){
        int x; cin >> x;
        x--; bad[x] = true;
    }
    REP(i, m){
        int u, v; cin >> u >> v;
        u--; v--;
        g.add_edge(u, v, 1);
    }
    possible_fractions.pb(0);
    possible_fractions.pb(1);
    REP(i, n) {
        FOR(j, 1, (int)g.adj[i].size()-1, 1){
            possible_fractions.pb((double)j / (double)g.adj[i].size());
        }
    }
    sort(possible_fractions.begin(), possible_fractions.end());
    double maxratio = solve(g);
    vi ans;
    check(maxratio, g, ans, true);
    cout << ans.size() << "\n";
    REP(i, ans.size()) cout << ans[i]+1 << " ";
    cout << "\n";

    return 0;
}


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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define FOR(i,j,k,in) for(int i=(j); i < (k);i+=in)
#define FORD(i,j,k,in) for(int i=(j); i >=(k);i-=in)
#define REP(i,b) FOR(i,0,b,1)
#define REPD(i,b) FORD(i,b,0,1)
#define pb push_back
#define mp make_pair
#define INF (int)1e9
#define MINF -(int)1e9
#define EPS 1e-9
#define MOD 1000000007
#define MOD2 998244353
#define PI 3.1415926535
#define ff first
#define ss second

#ifdef DEBUG
#define DBG if(1)
#else
#define DBG if(0)
#endif

#define dbg(x) cout << "(" << #x << " : " << x << ")" << endl;

template <class T, class U>
ostream& operator<<(ostream& out, const pair<T, U> &par) {
    out << "[" << par.first << ";" << par.second << "]";
    return out;
}

template <class T>
ostream& operator<<(ostream& out, const set<T> &cont) {
    out << "{";
    for( const auto &x:cont) out << x << ", ";
    out << "}";
    return out;
}

template <class T, class U>
ostream& operator<<(ostream& out, const map<T, U> &cont) {
    out << "{";
    for( const auto &x:cont) out << x << ", ";
    out << "}";
    return out;
}

template<class T>
ostream& operator<<(ostream& out, const vector<T> &v){
    out << "[";
    REP(i, v.size()) out << v[i] << ", ";
    out << "]";
    return out;
}
class edge{
    public:
        int src, dest;
        ll w;
        edge(int from, int to, ll weight){
            src = from;
            dest = to;
            w = weight;
        }
    };
class undigraph{
    public:
        int n;
        vector<edge> edges;
        vector<vi> adj;
        undigraph(int n){
            this->n = n;
            adj.resize(n);
        }
        void add_edge(int u, int v, ll w){
            edges.pb(edge(u, v, w));
            int id = edges.size()-1;
            adj[u].pb(id);
            adj[v].pb(id);
        }
    };
vector<bool> bad;
bool check(double x, undigraph &g, vi &ans, bool construct){
    // nejake menim na fortressy
    vector<bool> fortress = bad;
    queue<int> q;
    REP(i, g.n) {
        if (fortress[i]) continue;
        int good = 0;
        for (auto id : g.adj[i]) {
            edge e = g.edges[id];
            int other = i ^ e.src ^e.dest;
            if (!fortress[other]) good++;
        }
        if ((double) good / (double) g.adj[i].size() < x) q.push(i); // theoretically add EPS, cause doubles suck
    }
    while(!q.empty()){
        int v = q.front();
        q.pop();
        int good = 0;
        for(auto id : g.adj[v]){
            edge e = g.edges[id];
            int other = e.src ^ e.dest ^ v;
            if(!fortress[other]) good++;
        }
        if((double) good / (double) g.adj[v].size() < x){
            fortress[v] = true;
            for(auto id : g.adj[v]){
                edge e = g.edges[id];
                int other = e.src ^ e.dest ^ v;
                if(!fortress[other]) q.push(other);
            }
        }
    }
    if(!construct){
        bool can = false;
        REP(i, g.n){
            if(!fortress[i]) can = true;
        }
        return can;
    }
    else{
        REP(i, g.n){
            if(!fortress[i]) ans.pb(i);
        }
        return true;
    }
}
vector<double> possible_fractions;
double solve(undigraph &g){
    int l = 0;
    int r = possible_fractions.size()-1;
    int cnt = 0;
    vi temp;
    double ans = 0;
    while(l<=r){
        int m = (l+r)/2;
        if(check(possible_fractions[m], g, temp, false)){
            l = m + 1;
            ans = possible_fractions[m];
        }
        else r = m-1;
    }
    return ans;
}
// ocividne wa alebo tle ak zmenim cnt limit
// skusime ist cez vsetky mozne zlomky -> pre kazdy vrchol, pridam do setu vsetky x / pocet susedov
// takychto zlomkov tam bude radovo m
// snad to bude AC :)
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    int n,m,k; cin >> n >> m >> k;
    bad.resize(n);
    undigraph g(n);
    REP(i, k){
        int x; cin >> x;
        x--; bad[x] = true;
    }
    REP(i, m){
        int u, v; cin >> u >> v;
        u--; v--;
        g.add_edge(u, v, 1);
    }
    possible_fractions.pb(0);
    possible_fractions.pb(1);
    REP(i, n) {
        FOR(j, 1, (int)g.adj[i].size()-1, 1){
            possible_fractions.pb((double)j / (double)g.adj[i].size());
        }
    }
    sort(possible_fractions.begin(), possible_fractions.end());
    double maxratio = solve(g);
    vi ans;
    check(maxratio, g, ans, true);
    cout << ans.size() << "\n";
    REP(i, ans.size()) cout << ans[i]+1 << " ";
    cout << "\n";

    return 0;
}