#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <numeric>
#include <utility>
#include <cmath>
using namespace std; using namespace placeholders;
using LL = long long;
using ULL = unsigned long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VS = vector<string>;
using SS = stringstream;
using PII = pair<int,int>;
using VPII = vector< pair<int,int> >;
template < typename T = int > using VT = vector<T>;
template < typename T = int > using VVT = VT< VT<T> >;
template < typename T = int > using LIM = numeric_limits<T>;
template < typename T > inline T fromString( const string &s ){ T res; istringstream iss( s ); iss >> res; return res; };
template < typename T > inline string toString( const T &a ){ ostringstream oss; oss << a; return oss.str(); };
#define REP( i, m, n ) for ( int i = (int)( m ); i < (int)( n ); ++i )
#define FOR( e, c ) for ( auto &e : c )
#define ALL( c ) (c).begin(), (c).end()
#define AALL( a, t ) (t*)a, (t*)a + sizeof( a ) / sizeof( t )
#define DRANGE( c, p ) (c).begin(), (c).begin() + p, (c).end()
#define PB( n ) push_back( n )
#define MP( a, b ) make_pair( ( a ), ( b ) )
#define EXIST( c, e ) ( (c).find( e ) != (c).end() )
#define fst first
#define snd second
#define DUMP( x ) cerr << #x << " = " << ( x ) << endl
// 最大流( Dinic 法 ) O( |E||V|^2 )
class Dinic
{
struct Edge
{
int to, cap, rev;
Edge( int t, int c, int r ) : to( t ), cap( c ), rev( r ) {}
};
vector< vector<Edge> > G;
vector<int> distance, done;
public:
Dinic( int V ) : G( V ), distance( V ), done( V )
{
return;
}
void connect( int from, int to, int cost )
{
G[ from ].push_back( Edge( to, cost, G[ to ].size() ) );
G[ to ].push_back( Edge( from, 0, G[ from ].size() - 1 ) );
return;
}
int solve( int s, int t )
{
int res = 0;
while ( true )
{
bfs( s );
if ( distance[t] < 0 )
{
return res;
}
fill( done.begin(), done.end(), 0 );
for ( int f; ( f = dfs( s, t, numeric_limits<int>::max() ) ) > 0; res += f );
}
}
private:
void bfs( int s )
{
fill( distance.begin(), distance.end(), -1 );
distance[s] = 0;
queue<int> que;
que.push( s );
while ( !que.empty() )
{
int v = que.front();
que.pop();
for ( int i = 0; i < (int)G[v].size(); ++i )
{
Edge &e = G[v][i];
if ( e.cap > 0 && distance[ e.to ] < 0 )
{
distance[ e.to ] = distance[v] + 1;
que.push( e.to );
}
}
}
return;
}
int dfs( int v, int t, int f )
{
if ( v == t )
{
return f;
}
for ( int &i = done[v]; i < (int)G[v].size(); ++i )
{
Edge &e = G[v][i];
if ( e.cap > 0 && distance[v] < distance[ e.to ] )
{
int d = dfs( e.to, t, min( f, e.cap ) );
if ( d > 0 )
{
e.cap -= d;
G[ e.to ][ e.rev ].cap += d;
return d;
}
}
}
return 0;
}
};
// Dinic( |V| )
// connect( from, to, cap )
// solve( s, t )
int main()
{
cin.tie( 0 );
ios::sync_with_stdio( false );
int n, g, e;
cin >> n >> g >> e;
VI ps( g );
FOR( p, ps )
{
cin >> p;
}
Dinic maxflow( n + 2 );
const int SRC = n;
const int SINK = SRC + 1;
maxflow.connect( SRC, 0, n );
REP( iteraton, 0, e )
{
int a, b;
cin >> a >> b;
maxflow.connect( a, b, 1 );
maxflow.connect( b, a, 1 );
}
FOR( p, ps )
{
maxflow.connect( p, SINK, 1 );
}
cout << maxflow.solve( SRC, SINK ) << endl;
return 0;
}