/* in the name of Anton */      /*     Compete against Yourself.     Author - Aryan (@aryanc403)     Atcoder library - https://atcoder.github.io/ac-library/production/document_en/   */      #include <algorithm>   #include <cassert>   #include <limits>   #include <queue>   #include <vector>         #include <algorithm>   #include <utility>   #include <vector>      namespace atcoder {   namespace internal {      template <class E> struct csr {       std::vector<int> start;       std::vector<E> elist;       csr(int n, const std::vector<std::pair<int, E>>& edges)           : start(n + 1), elist(edges.size()) {           for (auto e : edges) {               start[e.first + 1]++;           }           for (int i = 1; i <= n; i++) {               start[i] += start[i - 1];           }           auto counter = start;           for (auto e : edges) {               elist[counter[e.first]++] = e.second;           }       }   };      }  // namespace internal      }  // namespace atcoder         #include <vector>      namespace atcoder {      namespace internal {      template <class T> struct simple_queue {       std::vector<T> payload;       int pos = 0;       void reserve(int n) { payload.reserve(n); }       int size() const { return int(payload.size()) - pos; }       bool empty() const { return pos == int(payload.size()); }       void push(const T& t) { payload.push_back(t); }       T& front() { return payload[pos]; }       void clear() {           payload.clear();           pos = 0;       }       void pop() { pos++; }   };      }  // namespace internal      }  // namespace atcoder         namespace atcoder {      template <class Cap, class Cost> struct mcf_graph {     public:       mcf_graph() {}       mcf_graph(int n) : _n(n) {}          int add_edge(int from, int to, Cap cap, Cost cost) {           assert(0 <= from && from < _n);           assert(0 <= to && to < _n);           assert(0 <= cap);           assert(0 <= cost);           int m = int(_edges.size());           _edges.push_back({from, to, cap, 0, cost});           return m;       }          struct edge {           int from, to;           Cap cap, flow;           Cost cost;       };          edge get_edge(int i) {           int m = int(_edges.size());           assert(0 <= i && i < m);           return _edges[i];       }       std::vector<edge> edges() { return _edges; }          std::pair<Cap, Cost> flow(int s, int t) {           return flow(s, t, std::numeric_limits<Cap>::max());       }       std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {           return slope(s, t, flow_limit).back();       }       std::vector<std::pair<Cap, Cost>> slope(int s, int t) {           return slope(s, t, std::numeric_limits<Cap>::max());       }       std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {           assert(0 <= s && s < _n);           assert(0 <= t && t < _n);           assert(s != t);              int m = int(_edges.size());           std::vector<int> edge_idx(m);              auto g = [&]() {               std::vector<int> degree(_n), redge_idx(m);               std::vector<std::pair<int, _edge>> elist;               elist.reserve(2 * m);               for (int i = 0; i < m; i++) {                   auto e = _edges[i];                   edge_idx[i] = degree[e.from]++;                   redge_idx[i] = degree[e.to]++;                   elist.push_back({e.from, {e.to, -1, e.cap - e.flow, e.cost}});                   elist.push_back({e.to, {e.from, -1, e.flow, -e.cost}});               }               auto _g = internal::csr<_edge>(_n, elist);               for (int i = 0; i < m; i++) {                   auto e = _edges[i];                   edge_idx[i] += _g.start[e.from];                   redge_idx[i] += _g.start[e.to];                   _g.elist[edge_idx[i]].rev = redge_idx[i];                   _g.elist[redge_idx[i]].rev = edge_idx[i];               }               return _g;           }();              auto result = slope(g, s, t, flow_limit);              for (int i = 0; i < m; i++) {               auto e = g.elist[edge_idx[i]];               _edges[i].flow = _edges[i].cap - e.cap;           }              return result;       }        private:       int _n;       std::vector<edge> _edges;          struct _edge {           int to, rev;           Cap cap;           Cost cost;       };          std::vector<std::pair<Cap, Cost>> slope(internal::csr<_edge>& g,                                               int s,                                               int t,                                               Cap flow_limit) {              std::vector<std::pair<Cost, Cost>> dual_dist(_n);           std::vector<int> prev_e(_n);           std::vector<bool> vis(_n);           struct Q {               Cost key;               int to;               bool operator<(Q r) const { return key > r.key; }           };           std::vector<int> que_min;           std::vector<Q> que;           auto dual_ref = [&]() {               for (int i = 0; i < _n; i++) {                   dual_dist[i].second = std::numeric_limits<Cost>::max();               }               std::fill(vis.begin(), vis.end(), false);               que_min.clear();               que.clear();                  size_t heap_r = 0;                  dual_dist[s].second = 0;               que_min.push_back(s);               while (!que_min.empty() || !que.empty()) {                   int v;                   if (!que_min.empty()) {                       v = que_min.back();                       que_min.pop_back();                   } else {                       while (heap_r < que.size()) {                           heap_r++;                           std::push_heap(que.begin(), que.begin() + heap_r);                       }                       v = que.front().to;                       std::pop_heap(que.begin(), que.end());                       que.pop_back();                       heap_r--;                   }                   if (vis[v]) continue;                   vis[v] = true;                   if (v == t) break;                   Cost dual_v = dual_dist[v].first, dist_v = dual_dist[v].second;                   for (int i = g.start[v]; i < g.start[v + 1]; i++) {                       auto e = g.elist[i];                       if (!e.cap) continue;                       Cost cost = e.cost - dual_dist[e.to].first + dual_v;                       if (dual_dist[e.to].second - dist_v > cost) {                           Cost dist_to = dist_v + cost;                           dual_dist[e.to].second = dist_to;                           prev_e[e.to] = e.rev;                           if (dist_to == dist_v) {                               que_min.push_back(e.to);                           } else {                               que.push_back(Q{dist_to, e.to});                           }                       }                   }               }               if (!vis[t]) {                   return false;               }                  for (int v = 0; v < _n; v++) {                   if (!vis[v]) continue;                   dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second;               }               return true;           };           Cap flow = 0;           Cost cost = 0, prev_cost_per_flow = -1;           std::vector<std::pair<Cap, Cost>> result = {{Cap(0), Cost(0)}};           while (flow < flow_limit) {               if (!dual_ref()) break;               Cap c = flow_limit - flow;               for (int v = t; v != s; v = g.elist[prev_e[v]].to) {                   c = std::min(c, g.elist[g.elist[prev_e[v]].rev].cap);               }               for (int v = t; v != s; v = g.elist[prev_e[v]].to) {                   auto& e = g.elist[prev_e[v]];                   e.cap += c;                   g.elist[e.rev].cap -= c;               }               Cost d = -dual_dist[s].first;               flow += c;               cost += c * d;               if (prev_cost_per_flow == d) {                   result.pop_back();               }               result.push_back({flow, cost});               prev_cost_per_flow = d;           }           return result;       }   };      }  // namespace atcoder         #ifdef ARYANC403       #include <header.h>   #else       #pragma GCC optimize ( Ofast )       #pragma GCC target ( sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx )       #pragma GCC optimize ( -ffloat-store )       #include<bits/stdc++.h>       #define dbg(args...) 42;   #endif      using namespace std;   #define fo(i,n)   for(i=0;i<(n);++i)   #define repA(i,j,n)   for(i=(j);i<=(n);++i)   #define repD(i,j,n)   for(i=(j);i>=(n);--i)   #define all(x) begin(x), end(x)   #define sz(x) ((lli)(x).size())   #define pb push_back   #define mp make_pair   #define X first   #define Y second   #define endl   n       typedef long long int lli;   typedef long double mytype;   typedef pair<lli,lli> ii;   typedef vector<ii> vii;   typedef vector<lli> vi;         const auto start_time = std::chrono::high_resolution_clock::now();   void aryanc403()   {   #ifdef ARYANC403   auto end_time = std::chrono::high_resolution_clock::now();   std::chrono::duration<double> diff = end_time-start_time;       cerr<< Time Taken :  <<diff.count()<<  n ;   #endif   }      const lli INF = 0xFFFFFFFFFFFFFFFL;      lli seed;   mt19937 rng(seed=chrono::steady_clock::now().time_since_epoch().count());   inline lli rnd(lli l=0,lli r=INF)   {return uniform_int_distribution<lli>(l,r)(rng);}      class CMP   {public:   bool operator()(ii a , ii b) //For min priority_queue .   {    return ! ( a.X < b.X || ( a.X==b.X && a.Y <= b.Y ));   }};      void add( map<lli,lli> &m, lli x,lli cnt=1)   {       auto jt=m.find(x);       if(jt==m.end())         m.insert({x,cnt});       else                    jt->Y+=cnt;   }      void del( map<lli,lli> &m, lli x,lli cnt=1)   {       auto jt=m.find(x);       if(jt->Y<=cnt)            m.erase(jt);       else                      jt->Y-=cnt;   }      bool cmp(const ii &a,const ii &b)   {       return a.X<b.X||(a.X==b.X&&a.Y<b.Y);   }      const lli mod = 1000000007L;   // const lli maxN = 1000000007L;          lli T,n,i,j,k,in,cnt,l,r,u,v,x,y;       lli m;       string s;       vi a;       vii b;       //priority_queue < ii , vector < ii > , CMP > pq;// min priority_queue .      lli countPaths(vii edges){       const int inf=1e9;       atcoder::mcf_graph<lli,lli> g(2*n + 2);       for(int i=0;i<n;++i){           g.add_edge(2*n,i,1,0);           g.add_edge(i+n,2*n+1,1,0);       }       for(auto x:edges){           g.add_edge(x.X,n+x.Y,1,inf-1);       }       return n-g.flow(2*n,2*n+1).X;   }      lli removeOne(vii &edges,int curVal){       for(int i=0;i<n;++i){           vii ed;           for(auto x:edges){               if(x.Y==i)                   continue;               ed.pb(x);           }           if(curVal==countPaths(ed)){               edges.swap(ed);               return -(i+1);           }              ed.clear();           for(auto x:edges){               if(x.X==i)                   continue;               ed.pb(x);           }           if(curVal==countPaths(ed)){               edges.swap(ed);               return (i+1);           }       }       assert(false);   }      vi solve(vii edges,lli k){       vi answers(k+1,-INF);       dbg(countPaths(edges));       const int st=countPaths(edges);       for(int fw=st;fw<=k;++fw){           answers[fw]=removeOne(edges,fw+1);       }       return answers;   }      int main(void) {       ios_base::sync_with_stdio(false);cin.tie(NULL);       // freopen( txt.in ,  r , stdin);       // freopen( txt.out ,  w , stdout);   // cout<<std::fixed<<std::setprecision(35);   // cin>>T;while(T--)   {          cin>>n>>m>>k;       vii edges;       fo(i,m)       {           cin>>u>>v;           u--;v--;           edges.pb({u,v});       }          auto operations=solve(edges,k);       b.resize(k+1);       for(int i=1;i<=k;++i){           cin>>b[i].X>>b[i].Y;           b[i].Y=min(b[i].X,b[i].Y);       }          b[0]={INF,1e12};       lli curVal=-INF;       vector<vi> ansb(k+1);       auto getBest=[&](const lli rest){           vector<vi> before(k+1);           auto bb=b;              auto insert=[&](const int place,const int op){               before[place].pb(op);               bb[place].X-=bb[place].Y;               bb[place].X=max(bb[place].X,0LL);               bb[place].Y=min(bb[place].Y,bb[place].X);           };              for(int i=1;i<rest&&i<=k;++i){               if(operations[i]==-INF)                   continue;               const int op=operations[i];               int place=0;               for(int j=1;j<=i;++j){                   if(bb[place].Y>bb[j].Y)                       place=j;               }               insert(place,op);           }              for(int i=rest;i<=k;++i){               if(operations[i]==-INF)                   continue;               const int op=operations[i];               insert(rest,op);           }              lli cst=0;           for(int i=1;i<=k;++i)               cst+=bb[i].X;           dbg(bb,cst);           if(cst>curVal){               curVal=cst;               ansb.swap(before);           }       };       for(int rest=1;rest<=k+1;++rest){           getBest(rest);       }       dbg(curVal);       vi ans;       for(int i=1;i<=k;++i){           for(auto x:ansb[i])               ans.pb(x);           ans.pb(0);       }          cout<<sz(ans)<<endl;       for(auto x:ans)           cout<<x<<   ;       cout<<endl;   }   aryanc403();       return 0;   }