#!/usr/bin/perl -w

use v5.16;

package IntComp;
use bigint;

sub new {
	my ($class, $mem, $inputs) = @_;
	my $self = {
		mem => [ @$mem ],
		pc  => 0,
		want_input => undef,
		base => 0,
	};
	$self->{inputs} = [ @$inputs ]
		if defined $inputs;
	bless $self, $class;
}

sub clone {
	my ($class, $other) = @_;
	my $self = {
		mem => [ @{ $other->{mem} } ],
		pc  => $other->{pc},
		want_input => undef,
		base => $other->{base},
		inputs => [ ],
	};
	bless $self, $class;
}

sub m2val {
	my ($self, $off, $mode) = @_;
	if ($mode == 0) {
		return $self->{mem}->[ $self->{mem}->[$self->{pc} + $off] ] // 0;
	} elsif ($mode == 1) {
		return $self->{mem}->[$self->{pc} + $off] // 0;
	} elsif ($mode == 2) {
		return $self->{mem}->[ $self->{mem}->[$self->{pc} + $off ] + $self->{base} ] // 0;
	}
}

sub m2pos {
	my ($self, $off, $mode) = @_;
	if ($mode == 0) {
		return $self->{mem}->[$self->{pc} + $off];
	} elsif ($mode == 2) {
		return $self->{mem}->[$self->{pc} + $off] + $self->{base};
	}
}

sub input {
	my ($self, @input) = @_;
	push @{ $self->{inputs} }, @input;
}

sub run {
	my ($self, @input) = @_;
	my $mem = $self->{mem};

	push @{ $self->{inputs} }, @input;
	if (defined $self->{want_input}) {
		$mem->[$self->{want_input}] = shift @{ $self->{inputs} };
		$self->{want_input} = undef;
	}

	while (1) {
		my $opcode = $mem->[$self->{pc}];
		# say "pc=", $self->{pc}, " opcode=$opcode";
		# say "mem=", join(',', map { $_ // '_' } @{ $self->{mem} });
		my $op = int($opcode % 100);
		my $m1 = int($opcode / 100) % 10;
		my $m2 = int($opcode / 1000) % 10;
		my $m3 = int($opcode / 10000) % 10;
		if ($op == 1) {
			$mem->[ m2pos($self, 3, $m3) ]
				= m2val($self, 1, $m1)
				+ m2val($self, 2, $m2);
			$self->{pc} += 4;
		} elsif ($op == 2) {
			$mem->[ m2pos($self, 3, $m3) ]
				= m2val($self, 1, $m1)
				* m2val($self, 2, $m2);
			$self->{pc} += 4;
		} elsif ($op == 3) {
			if (@{ $self->{inputs} }) {
				$mem->[ m2pos($self, 1, $m1) ]
					= shift @{ $self->{inputs} };
				$self->{pc} += 2;
			} else {
				$self->{want_input} = m2pos($self, 1, $m1);
				$self->{pc} += 2;
				return undef;
			}
		} elsif ($op == 4) {
			my $val = m2val($self, 1, $m1);
			$self->{pc} += 2;
			return $val;
		} elsif ($op == 5) {
			if (m2val($self, 1, $m1)) {
				$self->{pc} = m2val($self, 2, $m2);
			} else {
				$self->{pc} += 3;
			}
		} elsif ($op == 6) {
			if (!m2val($self, 1, $m1)) {
				$self->{pc} = m2val($self, 2, $m2);
			} else {
				$self->{pc} += 3;
			}
		} elsif ($op == 7) {
			$mem->[ m2pos($self, 3, $m3) ] =
				m2val($self, 1, $m1)
				< m2val($self, 2, $m2) ? 1 : 0;
			$self->{pc} += 4;
		} elsif ($op == 8) {
			$mem->[ m2pos($self, 3, $m3) ] =
				m2val($self, 1, $m1)
				== m2val($self, 2, $m2) ? 1 : 0;
			$self->{pc} += 4;
		} elsif ($op == 9) {
			$self->{base} += m2val($self, 1, $m1);
			$self->{pc} += 2;
		} elsif ($op == 99) {
			return undef;
		}
	}
}

package main;

chomp (my @mem = split /,/, <>);

$; = ',';

my @comps;
for (0 .. 49) {
	push @comps, IntComp->new(\@mem, [ $_ ]);
}

my @queues;
push @queues, [] for 1 .. 50;

my @nat;
my $prev_y;

while(1) {
	my $idle = 1;
	for my $i (0 .. 49) {
		my $c = $comps[$i];
		my $dst = $c->run;
		if (!defined $dst) {
			say "$i wants input";
			my $q = $queues[$i];
			if (defined $q->[0]) {
				my $in = shift @$q;
				$c->input(@$in);
				say "$i received @$in";
				$idle = 0;
			} else {
				say "$i queue empty";
				$c->input(-1);
			}
		} else {
			my ($x, $y) = ($c->run, $c->run);

			say "$i sends $dst $x $y";
			$idle = 0;
			if ($dst == 255) {
				@nat = ($x, $y);
			} else {
				my $q = $queues[$dst];
				push @$q, [$x, $y];
			}
		}
	}
	if ($idle) {
		say "all idle, sending ", join(' ', @nat), " to 0";
		$comps[0]->input(@nat);
		if (defined $prev_y && $nat[1] == $prev_y) {
			say "$prev_y sent second time";
			exit 0;
		}
		$prev_y = $nat[1];
	}
}
