program lygiagretus_procesoriai;

   const PRAD = 'proc.dat';
         REZ = 'proc.rez';
         MAX_U = 2000;
   type lent1 = array [1..MAX_U] of integer;
        sarasas = ^elem;
        elem = record
                 inf: integer;
                 tol: sarasas;
              end;
        lent2 = array [1..MAX_U] of sarasas;

  { ‘emiau apražyti globalieji kintamieji }
  var PRO, UZD: integer;
      po: lent1;   { kur veda lankai iž atitinkamos virž–n‚s }
      pries: lent2; { iž kur ateina lankai  atitinkam… virž–nŠ }
      sluoks: lent1; { virž–ni— sluoksniai }

  procedure deti_rikiuota (tmp: sarasas; var rik: sarasas);
    { element… traukia  rikiuot… ma‘‚jant s…raž… }
    var laik: sarasas;
  begin
    if rik = nil then
       begin rik := tmp; tmp^.tol := nil; end
    else if sluoks[rik^.inf] < sluoks[tmp^.inf]
            then begin
                   tmp^.tol := rik; rik := tmp;
                  end
    else begin
           laik := rik;
           while (laik^.tol <> nil) and
                 (sluoks[laik^.tol^.inf] > sluoks[tmp^.inf]) do
              laik := laik^.tol;
           tmp^.tol := laik^.tol;
           laik^.tol := tmp;
         end;
  end; { d‚ti_rikiuot… }

  procedure rikiuoti;
    { sluoksni— ma‘‚jimo tvarka surikiuojami "pries" s…ražai }
    var u: integer;
        rik, tmp: sarasas;
  begin
    for u := 1 to UZD do
      begin
        rik := nil;
        while pries[u] <> nil do
          begin
            tmp:= pries[u];
            pries[u] := pries[u]^.tol;
            deti_rikiuota (tmp, rik);
          end;
        pries[u] := rik;
      end;
  end; { rikiuoti }

  procedure ivykdyti_uzduotis (var vyk: sarasas);
    var rik, tmp, laik: sarasas;
        u, ind: integer;
  begin
    { atskiriami du s…ražai }
    tmp := vyk;
    ind := 1;
    while (ind < PRO) and (tmp <> nil) do
      begin
        ind := ind + 1;
        tmp := tmp^.tol;
      end;
    if tmp<>nil then
      begin
        rik := tmp^.tol;
        tmp^.tol := nil;
       end
    else rik:=nil;

    while vyk <> nil do
      begin
        u := vyk^.inf;
        { valomas s…ražas }
        laik := vyk;
        vyk := vyk^.tol;
        dispose (laik);


        {  s…raž… traukiami vaikai }
        while pries[u] <> nil do
          begin
            tmp:= pries[u];
            pries[u] := pries[u]^.tol;
            deti_rikiuota (tmp, rik);
          end;
      end;
    vyk := rik;
  end; { vykdyti_u‘duotis }

  procedure eiti (u, sluoksnis: integer);
    { rekursižkai skaido grafo virž–nes  sluoksnius }
    var v: integer;
  begin
    sluoksnis := sluoksnis + 1;
    v := po[u];
    if sluoksnis > sluoks[v]
       then sluoks[v] := sluoksnis;
    if po[v] <> 0 then eiti (v, sluoksnis);
  end; { eiti }

  procedure sluoksniai;
  { grafo virž–nes suskaido  sluoksnius }
    var u, sluoksnis: integer;
  begin
    for u := 1 to UZD do
      if pries[u] = nil
         then sluoks[u] := 1 { inicializuojami sluoksniai }
         else sluoks[u] := 0;
    sluoksnis := 1;
    for u := 1 to UZD do
      if sluoks[u] = 1
        then eiti (u, sluoksnis);
  end; { sluoksniai }

  function laikas_f: integer;
    { suskai‡iuoja per kiek laiko moment— bus vykdytos u‘duotys }
    var laikas, u, saknis: integer;
        vyk: sarasas;
  begin
    sluoksniai;  { virž–n‚s suskaidomos  sluoksnius }
    rikiuoti;    { virž–n‚s s…raže "priež" surikiuojamos sluoksni— }
    { randama žaknis }                           { ma‘‚jimo tvarka }
    for u := 1 to UZD do
      if po[u] = 0 then saknis := u;
    laikas := 1; { paskutiniajam darnbui - vienas momentas }
    vyk := pries[saknis];

    pries[saknis] := nil;
    while vyk <> nil do
      begin
        ivykdyti_uzduotis (vyk);
        laikas := laikas + 1;
      end;
    laikas_f := laikas;
  end; { laikas }

  procedure skaityti (var PRO, UZD: integer;
                      var po: lent1; var pries: lent2);
    var f: text;
        i, a, b, N: integer;
        p, pr: sarasas;
  begin
    assign (f, PRAD);
    reset (f);
    readln (f, PRO, UZD, N);
    { inicializuojami  virž–nes ateinan‡i— lank— s…ražai }
    for i := 1 to UZD do
      pries[i] := nil;
    { perskaitytos poros traukiamos  s…ražus }
    for i := 1 to N do
      begin
        readln (f, a, b);
        po[a] := b;
        new (p);
        p^.inf := a;
        pr := pries[b];
        p^.tol := pries[b];;
        pries[b] := p;
     end;
    close (f);
  end; { skaityti }

  procedure rasyti (rezult: integer);
    var f: text;
  begin
    assign (f, REZ);
    rewrite (f);
    writeln (f, rezult);
    close (f);
  end; { ražyti }

  var rezult, N: integer;
begin
  skaityti (PRO, UZD, po, pries);
  rezult := laikas_f;
  rasyti (rezult);
end.

