with Ada.Text_IO;
procedure Quine is
   use Ada.Text_IO;
   Q : constant Character := Character'Val (34);
   T : constant Character := Character'Val (126);
   B : constant Character := Character'Val (92);
   Data : constant String :=
      "with Ada.Text_IO;~procedure Quine is~   use Ada.Text_IO;~   Q : constant Character := Character'Val (34);~   T : constant Character := Character'Val (126);~   B : constant Character := Character'Val (92);~   Data : constant String :=~      \   procedure Nl (S : String) is~   begin~      for I in S'Range loop~         if S (I) = T then~            New_Line;~         else~            Put (S (I));~         end if;~      end loop;~   end Nl;~   procedure Qs (S : String) is~   begin~      Put (Q);~      for I in S'Range loop~         if S (I) = Q then~            Put (Q); Put (Q);~         else~            Put (S (I));~         end if;~      end loop;~      Put (Q);~   end Qs;~   Split : Integer := 0;~begin~   for I in Data'Range loop~      if Data (I) = B then~         Split := I;~         exit;~      end if;~   end loop;~   Nl (Data (Data'First .. Split - 1));~   Qs (Data);~   Put (';');~   New_Line;~   Nl (Data (Split + 1 .. Data'Last));~end Quine;~";
   procedure Nl (S : String) is
   begin
      for I in S'Range loop
         if S (I) = T then
            New_Line;
         else
            Put (S (I));
         end if;
      end loop;
   end Nl;
   procedure Qs (S : String) is
   begin
      Put (Q);
      for I in S'Range loop
         if S (I) = Q then
            Put (Q); Put (Q);
         else
            Put (S (I));
         end if;
      end loop;
      Put (Q);
   end Qs;
   Split : Integer := 0;
begin
   for I in Data'Range loop
      if Data (I) = B then
         Split := I;
         exit;
      end if;
   end loop;
   Nl (Data (Data'First .. Split - 1));
   Qs (Data);
   Put (';');
   New_Line;
   Nl (Data (Split + 1 .. Data'Last));
end Quine;